From a2c1ec0de341b1ce1cdfe7404901d5350d1f2929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 11:14:24 +0100 Subject: [PATCH 01/45] Add RPM package spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/.gitignore | 3 + rpm-package/README.md | 44 ++++++++++++ rpm-package/jellyfin.env | 27 +++++++ rpm-package/jellyfin.service | 15 ++++ rpm-package/jellyfin.spec | 135 +++++++++++++++++++++++++++++++++++ rpm-package/jellyfin.sudoers | 19 +++++ rpm-package/restart.sh | 6 ++ rpm-package/update-db.sh | 12 ++++ 8 files changed, 261 insertions(+) create mode 100644 rpm-package/.gitignore create mode 100644 rpm-package/README.md create mode 100644 rpm-package/jellyfin.env create mode 100644 rpm-package/jellyfin.service create mode 100644 rpm-package/jellyfin.spec create mode 100644 rpm-package/jellyfin.sudoers create mode 100755 rpm-package/restart.sh create mode 100755 rpm-package/update-db.sh diff --git a/rpm-package/.gitignore b/rpm-package/.gitignore new file mode 100644 index 0000000000..6019b98c22 --- /dev/null +++ b/rpm-package/.gitignore @@ -0,0 +1,3 @@ +*.rpm +*.zip +*.tar.gz \ No newline at end of file diff --git a/rpm-package/README.md b/rpm-package/README.md new file mode 100644 index 0000000000..1fba9eaadd --- /dev/null +++ b/rpm-package/README.md @@ -0,0 +1,44 @@ +# unoffical jellyfin RPM + + + +## ffmpeg + +The RPM package for Fedora/CentOS requires some additional repos as ffmpeg is not in the main repositories. + +```shell +# ffmpeg from RPMfusion free +# Fedora +$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm +# CentOS 7 +$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm +``` + +## In-App service control + +A sample sudoers-policy is located at `/usr/share/jellyfin/jellyfin-sudoers` which you need to review and copy to `/etc/sudoers.d`. +Use `install -D -m 0600 -o root -g root /usr/share/jellyfin/jellyfin-sudoers /etc/sudoers.d/jellyfin-sudoers` for the right permissions. +Finally uncomment JELLYFIN_RESTART_OPT in /etc/sysconfig/jellyfin and restart the service. + +## Database patching +To fix the paths in the emby database for a migration to jellyfin run the script: +```shell +/usr/share/jellyfin/update-db-paths.sh +``` +PS: Please **backup your emby database beforehand**. + +## Building with dotnet + +Jellyfin is build with `--self-contained` so no dotnet required for runtime. + +```shell +# dotnet required for building the RPM +# Fedora +$ sudo dnf copr enable @dotnet-sig/dotnet +# CentOS +$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm +``` + +## TODO + +- [ ] OpenSUSE \ No newline at end of file diff --git a/rpm-package/jellyfin.env b/rpm-package/jellyfin.env new file mode 100644 index 0000000000..a935db68ae --- /dev/null +++ b/rpm-package/jellyfin.env @@ -0,0 +1,27 @@ +# Jellyfin default configuration options + +# Use this file to override the default configurations; add additional +# options with JELLYFIN_ADD_OPTS. + +# To override the user or this config file's location, use +# /etc/systemd/system/jellyfin.service.d/override.conf + +# +# This is a POSIX shell fragment +# + +# +# General options +# + +# Tell jellyfin wich ffmpeg/ffprobe to use +# JELLYFIN_FFMPEG="-ffmpeg /usr/bin/ffmpeg -ffprobe /usr/bin/ffprobe" + +# Data directory +JELLYFIN_DATA="/var/lib/jellyfin" +# To enable In-App service control uncomment JELLYFIN_RESTART_OPT +# and install the sample sudo policy to Allow jellyfin group to start, stop and restart itself. +# /usr/share/jellyfin/jellyfin-sudoers to /etc/sudoers.d/ +# JELLYFIN_RESTART_OPT="-restartpath /usr/libexec/jellyfin/restart.sh" +# Additional options for the binary +JELLYFIN_ADD_OPTS="" \ No newline at end of file diff --git a/rpm-package/jellyfin.service b/rpm-package/jellyfin.service new file mode 100644 index 0000000000..26d82a825f --- /dev/null +++ b/rpm-package/jellyfin.service @@ -0,0 +1,15 @@ +[Unit] +After=network.target +Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. + +[Service] +EnvironmentFile=/etc/sysconfig/jellyfin +WorkingDirectory=/var/lib/jellyfin +ExecStart=/usr/bin/jellyfin -programdata ${JELLYFIN_DATA} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_ADD_OPTS} ${JELLYFIN_FFMPEG} +TimeoutSec=15 +Restart=on-failure +User=jellyfin +Group=jellyfin + +[Install] +WantedBy=multi-user.target diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec new file mode 100644 index 0000000000..af2f929b18 --- /dev/null +++ b/rpm-package/jellyfin.spec @@ -0,0 +1,135 @@ +%global debug_package %{nil} +# jellyfin commit to package +%global commit f8a720d3d8adbdb1f092a42e592dae37ba3f25bb +%global gittag v3.5.2-5 +%global shortcommit %(c=%{commit}; echo ${c:0:7}) +# Taglib-sharp commit of the submodule since github archive doesn't include submodules +%global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 +%global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) + +Name: jellyfin +Version: 3.5.2.git%{shortcommit} +Release: 3%{?dist} +Summary: The Free Software Media Browser. +License: GPLv2 +URL: https://jellyfin.media +Source0: https://github.com/%{name}/%{name}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz +Source1: jellyfin.service +Source2: jellyfin.env +Source3: jellyfin.sudoers +Source4: restart.sh +Source5: https://github.com/mono/taglib-sharp/archive/%{taglib_commit}/taglib-sharp-%{taglib_shortcommit}.tar.gz +Source6: update-db.sh + +%{?systemd_requires} +BuildRequires: systemd +Requires(pre): shadow-utils +BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel +Requires: libcurl, fontconfig, freetype, openssl, glibc libicu +# Requirements not packaged in main repos +# COPR @dotnet-sig/dotnet +BuildRequires: dotnet-sdk-2.2 +# RPMfusion free +Requires: ffmpeg + +# For the update-db-paths.sh script to fix emby paths to jellyfin +Recommends: sqlite + +# Fedora has openssl1.1 which is incompatible with dotnet +%{?fedora:Requires: compat-openssl10} +# Disable Automatic Dependency Processing for Centos +%{?el7:AutoReqProv: no} + +%description +Jellyfin is a free software media system that puts you in control of managing and streaming your media. + + +%prep +%autosetup -n %{name}-%{commit} +pushd ThirdParty + tar xf %{S:5} + rm -rf taglib-sharp + mv taglib-sharp-%{taglib_commit} taglib-sharp +popd + +%build +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +dotnet build --runtime linux-x64 + +%install +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime linux-x64 +%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE +%{__install} -D -m 0644 debian/conf/jellyfin.service.conf %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__mkdir} -p %{buildroot}%{_bindir} +tee %{buildroot}%{_bindir}/jellyfin << EOF +#!/bin/sh +exec %{_libdir}/%{name}/%{name} \${@} +EOF +%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin +%{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service +%{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} +%{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_datadir}/%{name}/%{name}-sudoers +%{__install} -D -m 0750 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh +%{__install} -D -m 0755 %{SOURCE6} %{buildroot}%{_datadir}/%{name}/update-db-paths.sh + +%files +%{_libdir}/%{name}/dashboard-ui/* +%attr(755,root,root) %{_bindir}/%{name} +%attr(644,root,root) %{_libdir}/%{name}/*.json +%attr(644,root,root) %{_libdir}/%{name}/*.pdb +%attr(755,root,root) %{_libdir}/%{name}/*.dll +%attr(755,root,root) %{_libdir}/%{name}/*.so +%attr(755,root,root) %{_libdir}/%{name}/*.a +%attr(755,root,root) %{_libdir}/%{name}/createdump +%attr(755,root,root) %{_libdir}/%{name}/jellyfin +%attr(644,root,root) %{_libdir}/%{name}/sosdocsunix.txt +%attr(644,root,root) %{_unitdir}/%{name}.service +%attr(600,root,root) %{_datadir}/%{name}/%{name}-sudoers +%attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh +%attr(750,root,root) %{_libexecdir}/%{name}/restart.sh +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%attr(-,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin +%if 0%{?fedora} +%license LICENSE +%else +%{_datadir}/licenses/%{name}/LICENSE +%endif + +%pre +getent group jellyfin >/dev/null || groupadd -r jellyfin +getent passwd jellyfin >/dev/null || \ + useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ + -c "Jellyfin default user" jellyfin +exit 0 + +%post +%systemd_post jellyfin.service + +%preun +%systemd_preun jellyfin.service + +%postun +%systemd_postun_with_restart jellyfin.service + +%posttrans +echo -e "\e[31m +To enable In-App service control copy the sudo-policy (be sure to check it contents) with: + +install -D -m 0600 %{_datadir}/%{name}/%{name}-sudoers %{_sysconfdir}/sudoers.d/%{name}-sudoers + +and uncomment JELLYFIN_RESTART_OPT in %{_sysconfdir}/sysconfig/%{name} \e[0m" >> /dev/stderr + +%changelog +* Sat Jan 05 2019 Thomas Büttner - 3.5.2-3 +- Added script for database migration + +* Fri Jan 04 2019 Thomas Büttner - 3.5.2-2 +- Moved sudoers policy and added a note for In-App service control +- Set Restart=on-failure in jellyfin.service + +* Thu Jan 03 2019 Thomas Büttner - 3.5.2-1 +- Initial RPM package diff --git a/rpm-package/jellyfin.sudoers b/rpm-package/jellyfin.sudoers new file mode 100644 index 0000000000..b31d52f7ec --- /dev/null +++ b/rpm-package/jellyfin.sudoers @@ -0,0 +1,19 @@ +# Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin + + +%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD + +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty + +# Uncomment to allow the server to mount iso images +# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount +# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:%jellyfin !requiretty diff --git a/rpm-package/restart.sh b/rpm-package/restart.sh new file mode 100755 index 0000000000..e84dca587f --- /dev/null +++ b/rpm-package/restart.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +NAME=jellyfin +restart_cmd="/usr/bin/systemctl restart ${NAME}" +echo "sleep 2; sudo $restart_cmd > /dev/null 2>&1" | at now > /dev/null 2>&1 +exit 0 \ No newline at end of file diff --git a/rpm-package/update-db.sh b/rpm-package/update-db.sh new file mode 100755 index 0000000000..5866495126 --- /dev/null +++ b/rpm-package/update-db.sh @@ -0,0 +1,12 @@ +#!/bin/sh +db=${1:-/var/lib/jellyfin/data/library.db} +embypath=${2:-/var/lib/emby-server} +jellyfinpath=${3:-/var/lib/jellyfin} +sqlite3 ${db} << SQL +UPDATE Chapters2 +SET ImagePath=REPLACE(ImagePath, '${embypath}', '${jellyfinpath}'); +UPDATE TypedBaseItems +SET Path=REPLACE(Path, '${embypath}', '${jellyfinpath}'); +UPDATE TypedBaseItems +SET data=REPLACE(data, '${embypath}', '${jellyfinpath}'); +SQL From a968913e9f855a99435c7506431a5ec3d3ba1f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 11:22:03 +0100 Subject: [PATCH 02/45] CentOS Build fails since it has no Recommends: tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/README.md | 1 + rpm-package/jellyfin.spec | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rpm-package/README.md b/rpm-package/README.md index 1fba9eaadd..bbc8e7348e 100644 --- a/rpm-package/README.md +++ b/rpm-package/README.md @@ -21,6 +21,7 @@ Use `install -D -m 0600 -o root -g root /usr/share/jellyfin/jellyfin-sudoers /et Finally uncomment JELLYFIN_RESTART_OPT in /etc/sysconfig/jellyfin and restart the service. ## Database patching +You may need to install sqlite since CentOS has no `Recommends:` with `yum install sqlite`. To fix the paths in the emby database for a migration to jellyfin run the script: ```shell /usr/share/jellyfin/update-db-paths.sh diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index af2f929b18..5cadf779d5 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -33,7 +33,7 @@ BuildRequires: dotnet-sdk-2.2 Requires: ffmpeg # For the update-db-paths.sh script to fix emby paths to jellyfin -Recommends: sqlite +%{?fedora:Recommends: sqlite} # Fedora has openssl1.1 which is incompatible with dotnet %{?fedora:Requires: compat-openssl10} From 0eafc3fd1136a4c1356812d89650331002b9b666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 17:47:57 +0100 Subject: [PATCH 03/45] Update update-db.sh --- rpm-package/update-db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpm-package/update-db.sh b/rpm-package/update-db.sh index 5866495126..92c13cb8a9 100755 --- a/rpm-package/update-db.sh +++ b/rpm-package/update-db.sh @@ -1,7 +1,7 @@ #!/bin/sh -db=${1:-/var/lib/jellyfin/data/library.db} embypath=${2:-/var/lib/emby-server} jellyfinpath=${3:-/var/lib/jellyfin} +db=${1:-${jellyfinpath}/data/library.db} sqlite3 ${db} << SQL UPDATE Chapters2 SET ImagePath=REPLACE(ImagePath, '${embypath}', '${jellyfinpath}'); From b3de385d5b94166b32c67c63345c282e6564c11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 21:30:45 +0100 Subject: [PATCH 04/45] Re-add sudo policy for in-app service restart. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/README.md | 11 +++++++---- rpm-package/jellyfin.env | 6 ++---- rpm-package/jellyfin.spec | 17 ++++++----------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/rpm-package/README.md b/rpm-package/README.md index bbc8e7348e..84aded8c6a 100644 --- a/rpm-package/README.md +++ b/rpm-package/README.md @@ -14,11 +14,14 @@ $ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-re $ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm ``` -## In-App service control +## ISO mounting + +To allow jellyfin to mount/umonut ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` +``` +# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount +# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount +``` -A sample sudoers-policy is located at `/usr/share/jellyfin/jellyfin-sudoers` which you need to review and copy to `/etc/sudoers.d`. -Use `install -D -m 0600 -o root -g root /usr/share/jellyfin/jellyfin-sudoers /etc/sudoers.d/jellyfin-sudoers` for the right permissions. -Finally uncomment JELLYFIN_RESTART_OPT in /etc/sysconfig/jellyfin and restart the service. ## Database patching You may need to install sqlite since CentOS has no `Recommends:` with `yum install sqlite`. diff --git a/rpm-package/jellyfin.env b/rpm-package/jellyfin.env index a935db68ae..2e2b2ba8e5 100644 --- a/rpm-package/jellyfin.env +++ b/rpm-package/jellyfin.env @@ -19,9 +19,7 @@ # Data directory JELLYFIN_DATA="/var/lib/jellyfin" -# To enable In-App service control uncomment JELLYFIN_RESTART_OPT -# and install the sample sudo policy to Allow jellyfin group to start, stop and restart itself. -# /usr/share/jellyfin/jellyfin-sudoers to /etc/sudoers.d/ -# JELLYFIN_RESTART_OPT="-restartpath /usr/libexec/jellyfin/restart.sh" +# In-App service control +JELLYFIN_RESTART_OPT="-restartpath /usr/libexec/jellyfin/restart.sh" # Additional options for the binary JELLYFIN_ADD_OPTS="" \ No newline at end of file diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 5cadf779d5..090f6e319b 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -9,7 +9,7 @@ Name: jellyfin Version: 3.5.2.git%{shortcommit} -Release: 3%{?dist} +Release: 4%{?dist} Summary: The Free Software Media Browser. License: GPLv2 URL: https://jellyfin.media @@ -71,7 +71,7 @@ EOF %{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin %{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} -%{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_datadir}/%{name}/%{name}-sudoers +%{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers %{__install} -D -m 0750 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh %{__install} -D -m 0755 %{SOURCE6} %{buildroot}%{_datadir}/%{name}/update-db-paths.sh @@ -87,10 +87,10 @@ EOF %attr(755,root,root) %{_libdir}/%{name}/jellyfin %attr(644,root,root) %{_libdir}/%{name}/sosdocsunix.txt %attr(644,root,root) %{_unitdir}/%{name}.service -%attr(600,root,root) %{_datadir}/%{name}/%{name}-sudoers %attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh %attr(750,root,root) %{_libexecdir}/%{name}/restart.sh %config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers %config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %attr(-,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin %if 0%{?fedora} @@ -115,15 +115,10 @@ exit 0 %postun %systemd_postun_with_restart jellyfin.service -%posttrans -echo -e "\e[31m -To enable In-App service control copy the sudo-policy (be sure to check it contents) with: - -install -D -m 0600 %{_datadir}/%{name}/%{name}-sudoers %{_sysconfdir}/sudoers.d/%{name}-sudoers - -and uncomment JELLYFIN_RESTART_OPT in %{_sysconfdir}/sysconfig/%{name} \e[0m" >> /dev/stderr - %changelog +* Sat Jan 05 2019 Thomas Büttner - 3.5.2-4 +- Re-added sudoers policy + * Sat Jan 05 2019 Thomas Büttner - 3.5.2-3 - Added script for database migration From 90ab6a40fcdc97bd845c67e65f916210de59552d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 22:06:10 +0100 Subject: [PATCH 05/45] add Firewalld serivce.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin-firewalld.xml | 9 +++++++++ rpm-package/jellyfin.spec | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 rpm-package/jellyfin-firewalld.xml diff --git a/rpm-package/jellyfin-firewalld.xml b/rpm-package/jellyfin-firewalld.xml new file mode 100644 index 0000000000..062db370da --- /dev/null +++ b/rpm-package/jellyfin-firewalld.xml @@ -0,0 +1,9 @@ + + + Jellyfin + The Free Software Media System. + + + + + \ No newline at end of file diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 090f6e319b..17da904269 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -9,7 +9,7 @@ Name: jellyfin Version: 3.5.2.git%{shortcommit} -Release: 4%{?dist} +Release: 5%{?dist} Summary: The Free Software Media Browser. License: GPLv2 URL: https://jellyfin.media @@ -20,6 +20,7 @@ Source3: jellyfin.sudoers Source4: restart.sh Source5: https://github.com/mono/taglib-sharp/archive/%{taglib_commit}/taglib-sharp-%{taglib_shortcommit}.tar.gz Source6: update-db.sh +Source7: jellyfin-firewalld.xml %{?systemd_requires} BuildRequires: systemd @@ -74,6 +75,7 @@ EOF %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers %{__install} -D -m 0750 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh %{__install} -D -m 0755 %{SOURCE6} %{buildroot}%{_datadir}/%{name}/update-db-paths.sh +%{__install} -D -m 0755 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml %files %{_libdir}/%{name}/dashboard-ui/* @@ -89,6 +91,7 @@ EOF %attr(644,root,root) %{_unitdir}/%{name}.service %attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh %attr(750,root,root) %{_libexecdir}/%{name}/restart.sh +%attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers %config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf @@ -116,6 +119,9 @@ exit 0 %systemd_postun_with_restart jellyfin.service %changelog +* Sat Jan 05 2019 Thomas Büttner - 3.5.2-5 +- Add firewalld service.xml + * Sat Jan 05 2019 Thomas Büttner - 3.5.2-4 - Re-added sudoers policy From 79229fe3ae80bd0f10d2aadb09737170ce0af936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Sat, 5 Jan 2019 22:44:46 +0100 Subject: [PATCH 06/45] bump to 10.0.0 and use simple version scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 17da904269..5b53bd005e 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -1,19 +1,17 @@ %global debug_package %{nil} -# jellyfin commit to package -%global commit f8a720d3d8adbdb1f092a42e592dae37ba3f25bb -%global gittag v3.5.2-5 -%global shortcommit %(c=%{commit}; echo ${c:0:7}) +# jellyfin tag to package +%global gittag v10.0.0 # Taglib-sharp commit of the submodule since github archive doesn't include submodules %global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 %global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) Name: jellyfin -Version: 3.5.2.git%{shortcommit} -Release: 5%{?dist} +Version: 10.0.0 +Release: 1%{?dist} Summary: The Free Software Media Browser. License: GPLv2 URL: https://jellyfin.media -Source0: https://github.com/%{name}/%{name}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz +Source0: https://github.com/%{name}/%{name}/archive/%{gittag}.tar.gz Source1: jellyfin.service Source2: jellyfin.env Source3: jellyfin.sudoers @@ -46,7 +44,7 @@ Jellyfin is a free software media system that puts you in control of managing an %prep -%autosetup -n %{name}-%{commit} +%autosetup -n %{name}-%{version} pushd ThirdParty tar xf %{S:5} rm -rf taglib-sharp @@ -119,6 +117,9 @@ exit 0 %systemd_postun_with_restart jellyfin.service %changelog +* Sat Jan 05 2019 Thomas Büttner - 10.0.0-1 +- Bump version to 10.0.0 + * Sat Jan 05 2019 Thomas Büttner - 3.5.2-5 - Add firewalld service.xml From cbff18edb5ce0921cad626264708e3de4ebe0832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Mon, 7 Jan 2019 18:51:37 +0100 Subject: [PATCH 07/45] Add logging and config directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.env | 6 ++++-- rpm-package/jellyfin.service | 2 +- rpm-package/jellyfin.spec | 10 +++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/rpm-package/jellyfin.env b/rpm-package/jellyfin.env index 2e2b2ba8e5..827a33f468 100644 --- a/rpm-package/jellyfin.env +++ b/rpm-package/jellyfin.env @@ -17,8 +17,10 @@ # Tell jellyfin wich ffmpeg/ffprobe to use # JELLYFIN_FFMPEG="-ffmpeg /usr/bin/ffmpeg -ffprobe /usr/bin/ffprobe" -# Data directory -JELLYFIN_DATA="/var/lib/jellyfin" +# Program directories +JELLYFIN_DATA_DIRECTORY="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIRECTORY="/etc/jellyfin" +JELLYFIN_LOG_DIRECTORY="/var/log/jellyfin" # In-App service control JELLYFIN_RESTART_OPT="-restartpath /usr/libexec/jellyfin/restart.sh" # Additional options for the binary diff --git a/rpm-package/jellyfin.service b/rpm-package/jellyfin.service index 26d82a825f..0ece5b57f4 100644 --- a/rpm-package/jellyfin.service +++ b/rpm-package/jellyfin.service @@ -5,7 +5,7 @@ Description=Jellyfin is a free software media system that puts you in control of [Service] EnvironmentFile=/etc/sysconfig/jellyfin WorkingDirectory=/var/lib/jellyfin -ExecStart=/usr/bin/jellyfin -programdata ${JELLYFIN_DATA} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_ADD_OPTS} ${JELLYFIN_FFMPEG} +ExecStart=/usr/bin/jellyfin -programdata ${JELLYFIN_DATA_DIRECTORY} -configdir ${JELLYFIN_CONFIG_DIRECTORY} -logdir ${JELLYFIN_LOG_DIRECTORY} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_ADD_OPTS} ${JELLYFIN_FFMPEG} TimeoutSec=15 Restart=on-failure User=jellyfin diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 5b53bd005e..a7619ea05c 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -62,12 +62,16 @@ export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime linux-x64 %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE %{__install} -D -m 0644 debian/conf/jellyfin.service.conf %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__install} -D -m 0644 debian/conf/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json %{__mkdir} -p %{buildroot}%{_bindir} tee %{buildroot}%{_bindir}/jellyfin << EOF #!/bin/sh exec %{_libdir}/%{name}/%{name} \${@} EOF %{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin +%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name} +%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin + %{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers @@ -90,10 +94,13 @@ EOF %attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh %attr(750,root,root) %{_libexecdir}/%{name}/restart.sh %attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml +%attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers %config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json %attr(-,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin +%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin %if 0%{?fedora} %license LICENSE %else @@ -117,8 +124,9 @@ exit 0 %systemd_postun_with_restart jellyfin.service %changelog -* Sat Jan 05 2019 Thomas Büttner - 10.0.0-1 +* Mon Jan 07 2019 Thomas Büttner - 10.0.0-1 - Bump version to 10.0.0 +- Add logging and config directories * Sat Jan 05 2019 Thomas Büttner - 3.5.2-5 - Add firewalld service.xml From 0e455b0f6232751d72580b5454303cfaee371aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Mon, 7 Jan 2019 19:28:04 +0100 Subject: [PATCH 08/45] fixed restart.sh permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index a7619ea05c..c55d1d2605 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -92,7 +92,7 @@ EOF %attr(644,root,root) %{_libdir}/%{name}/sosdocsunix.txt %attr(644,root,root) %{_unitdir}/%{name}.service %attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh -%attr(750,root,root) %{_libexecdir}/%{name}/restart.sh +%attr(755,root,root) %{_libexecdir}/%{name}/restart.sh %attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml %attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} %config(noreplace) %{_sysconfdir}/sysconfig/%{name} From 7f4a073b05ac9c4ce4ef6d499cd5bfba40f72415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Tue, 8 Jan 2019 18:56:55 +0100 Subject: [PATCH 09/45] Add %post script to move exitsting config to /etc/jellyfin and symlink it. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index c55d1d2605..f6585a3d34 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -95,7 +95,7 @@ EOF %attr(755,root,root) %{_libexecdir}/%{name}/restart.sh %attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml %attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} -%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config %{_sysconfdir}/sysconfig/%{name} %config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers %config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json @@ -115,6 +115,21 @@ getent passwd jellyfin >/dev/null || \ exit 0 %post +# Move existing configuration to /etc/jellyfin and symlink config to /etc/jellyfin +if [ $1 -gt 1 ] ; then + if [ ! -L %{_sharedstatedir}/%{name}/config ]; then + service_state=$(systemctl is-active jellyfin.service) + if [ "${service_state}" = "active" ]; then + systemctl stop jellyfin.service + fi + mv %{_sharedstatedir}/%{name}/config/* %{_sysconfdir}/%{name}/ + rmdir %{_sharedstatedir}/%{name}/config + ln -sf %{_sysconfdir}/%{name} %{_sharedstatedir}/%{name}/config + if [ "${service_state}" = "active" ]; then + systemctl start jellyfin.service + fi + fi +fi %systemd_post jellyfin.service %preun @@ -127,6 +142,7 @@ exit 0 * Mon Jan 07 2019 Thomas Büttner - 10.0.0-1 - Bump version to 10.0.0 - Add logging and config directories +- Add %post script to move exitsting config to /etc/jellyfin and symlink it. * Sat Jan 05 2019 Thomas Büttner - 3.5.2-5 - Add firewalld service.xml From ad36f9ec8951de61a605ceb247296a884e81f6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Tue, 8 Jan 2019 19:04:52 +0100 Subject: [PATCH 10/45] Add rpm build script for fedora and update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/Dockerfile.fedora_package | 17 +++++++++++++++++ rpm-package/README.md | 16 ++++++++++------ rpm-package/build-fedora-rpm.sh | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 rpm-package/Dockerfile.fedora_package create mode 100755 rpm-package/build-fedora-rpm.sh diff --git a/rpm-package/Dockerfile.fedora_package b/rpm-package/Dockerfile.fedora_package new file mode 100644 index 0000000000..35650106d1 --- /dev/null +++ b/rpm-package/Dockerfile.fedora_package @@ -0,0 +1,17 @@ +FROM fedora:29 +ARG HOME=/build +RUN mkdir /build && \ + dnf install -y @buildsys-build rpmdevtools dnf-plugins-core && \ + dnf copr enable -y @dotnet-sig/dotnet && \ + rpmdev-setuptree + +WORKDIR /build/rpmbuild +COPY jellyfin.spec SPECS +COPY . SOURCES + +RUN spectool -g -R SPECS/jellyfin.spec && \ + rpmbuild -bs SPECS/jellyfin.spec && \ + dnf build-dep -y SRPMS/jellyfin-*.src.rpm && \ + rpmbuild -bb SPECS/jellyfin.spec && \ + mkdir /jellyfin && \ + find . -name 'jellyfin-*.rpm' -print -exec cp {} /jellyfin \; \ No newline at end of file diff --git a/rpm-package/README.md b/rpm-package/README.md index 84aded8c6a..5944f9e9b0 100644 --- a/rpm-package/README.md +++ b/rpm-package/README.md @@ -1,29 +1,33 @@ -# unoffical jellyfin RPM +# Jellyfin RPM - +## Build Fedora Package with docker + +Change into this directory `cd rpm-package` +Run the build script `./build-fedora-rpm.sh`. +Resulting RPM and src.rpm will be in `../../jellyfin-*.rpm` ## ffmpeg -The RPM package for Fedora/CentOS requires some additional repos as ffmpeg is not in the main repositories. +The RPM package for Fedora/CentOS requires some additional repositories as ffmpeg is not in the main repositories. ```shell # ffmpeg from RPMfusion free # Fedora $ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm -# CentOS 7 +# CentOS 7 $ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm ``` ## ISO mounting -To allow jellyfin to mount/umonut ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` +To allow Jellyfin to mount/umonut ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` ``` # %jellyfin ALL=(ALL) NOPASSWD: /bin/mount # %jellyfin ALL=(ALL) NOPASSWD: /bin/umount ``` - ## Database patching + You may need to install sqlite since CentOS has no `Recommends:` with `yum install sqlite`. To fix the paths in the emby database for a migration to jellyfin run the script: ```shell diff --git a/rpm-package/build-fedora-rpm.sh b/rpm-package/build-fedora-rpm.sh new file mode 100755 index 0000000000..87c94e0812 --- /dev/null +++ b/rpm-package/build-fedora-rpm.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env sh + +# Build a Jellyfin .rpm file with Docker on Linux +# Places the output .rpm file in the parent directory + +set -o errexit +set -o xtrace +set -o nounset + +package_temporary_dir="`mktemp -d`" +current_user="`whoami`" +image_name="jellyfin-rpmbuild" + +cleanup() { + set +o errexit + docker image rm $image_name --force + rm -rf "$package_temporary_dir" +} +trap cleanup EXIT INT + +docker build . -t "$image_name" -f ./Dockerfile.fedora_package +docker run --rm -v "$package_temporary_dir:/temp" "$image_name" cp -r /jellyfin /temp/ +sudo chown -R "$current_user" "$package_temporary_dir" +mv "$package_temporary_dir"/jellyfin/*.rpm ../../ From 4e7f4754917a2ec5814cbd495532e4765e165773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Tue, 8 Jan 2019 19:44:51 +0100 Subject: [PATCH 11/45] Also symlink logs to /var/log, changed changelog to lastest entry of the debian package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 45 ++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index f6585a3d34..315a542e39 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -117,17 +117,22 @@ exit 0 %post # Move existing configuration to /etc/jellyfin and symlink config to /etc/jellyfin if [ $1 -gt 1 ] ; then + service_state=$(systemctl is-active jellyfin.service) + if [ "${service_state}" = "active" ]; then + systemctl stop jellyfin.service + fi if [ ! -L %{_sharedstatedir}/%{name}/config ]; then - service_state=$(systemctl is-active jellyfin.service) - if [ "${service_state}" = "active" ]; then - systemctl stop jellyfin.service - fi mv %{_sharedstatedir}/%{name}/config/* %{_sysconfdir}/%{name}/ rmdir %{_sharedstatedir}/%{name}/config ln -sf %{_sysconfdir}/%{name} %{_sharedstatedir}/%{name}/config - if [ "${service_state}" = "active" ]; then - systemctl start jellyfin.service - fi + fi + if [ ! -L %{_sharedstatedir}/%{name}/logs ]; then + mv %{_sharedstatedir}/%{name}/logs/* %{_var}/log/jellyfin + rmdir %{_sharedstatedir}/%{name}/logs + ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs + fi + if [ "${service_state}" = "active" ]; then + systemctl start jellyfin.service fi fi %systemd_post jellyfin.service @@ -139,23 +144,9 @@ fi %systemd_postun_with_restart jellyfin.service %changelog -* Mon Jan 07 2019 Thomas Büttner - 10.0.0-1 -- Bump version to 10.0.0 -- Add logging and config directories -- Add %post script to move exitsting config to /etc/jellyfin and symlink it. - -* Sat Jan 05 2019 Thomas Büttner - 3.5.2-5 -- Add firewalld service.xml - -* Sat Jan 05 2019 Thomas Büttner - 3.5.2-4 -- Re-added sudoers policy - -* Sat Jan 05 2019 Thomas Büttner - 3.5.2-3 -- Added script for database migration - -* Fri Jan 04 2019 Thomas Büttner - 3.5.2-2 -- Moved sudoers policy and added a note for In-App service control -- Set Restart=on-failure in jellyfin.service - -* Thu Jan 03 2019 Thomas Büttner - 3.5.2-1 -- Initial RPM package +* Tue Jan 08 2019 Thomas Büttner - 10.0.0-1 +- The first Jellyfin release under our new versioning scheme +- Numerous bugfixes and code readability improvements +- Updated logging configuration, including flag for it and configdir +- Updated theming including logo +- Dozens of other improvements as documented in GitHub pull request 419 From 399a079dd472a0ad424884eb48a0d9e471a95c70 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Thu, 10 Jan 2019 19:45:21 +0100 Subject: [PATCH 12/45] Build scripts and build system consolidation. Squashed commit. --- .dockerignore | 3 + .drone.yml | 2 +- .gitignore | 34 +-- build-deb.sh | 24 -- debian/bin/jellyfin-sudoers | 37 --- debian/bin/restart.sh | 18 -- debian/source/options | 1 - deployment/README.md | 8 + deployment/build.sh | 23 ++ deployment/clean.sh | 21 ++ deployment/collect_all.sh | 20 ++ deployment/common.build.sh | 108 +++++++++ .../debian-package-x64/Dockerfile | 13 +- deployment/debian-package-x64/clean.sh | 7 + deployment/debian-package-x64/package.sh | 33 +++ .../debian-package-x64/pkg-src}/changelog | 0 .../debian-package-x64/pkg-src}/compat | 0 .../debian-package-x64/pkg-src}/conf/jellyfin | 0 .../pkg-src}/conf/jellyfin.service.conf | 0 .../pkg-src}/conf/logging.json | 0 .../debian-package-x64/pkg-src}/control | 0 .../debian-package-x64/pkg-src}/copyright | 0 .../debian-package-x64/pkg-src}/gbp.conf | 2 +- .../debian-package-x64/pkg-src}/install | 0 .../debian-package-x64/pkg-src}/jellyfin.init | 0 .../pkg-src}/jellyfin.service | 0 .../pkg-src}/jellyfin.upstart | 0 .../pkg-src}/po/POTFILES.in | 0 .../pkg-src}/po/templates.pot | 0 .../debian-package-x64/pkg-src}/postinst | 0 .../debian-package-x64/pkg-src}/postrm | 0 .../debian-package-x64/pkg-src}/preinst | 0 .../debian-package-x64/pkg-src}/prerm | 0 .../debian-package-x64/pkg-src}/rules | 6 +- .../pkg-src}/source.lintian-overrides | 0 .../debian-package-x64/pkg-src}/source/format | 0 .../debian-package-x64/pkg-src/source/options | 11 + deployment/debian-x64/build.sh | 7 + deployment/debian-x64/clean.sh | 7 + deployment/debian-x64/package.sh | 7 + Dockerfile => deployment/docker/Dockerfile | 4 +- .../docker/Dockerfile.aarch64 | 2 +- deployment/docker/build.sh | 7 + deployment/framework/build.sh | 8 + deployment/framework/clean.sh | 7 + deployment/framework/package.sh | 7 + deployment/linux-x64/build.sh | 7 + deployment/linux-x64/clean.sh | 7 + deployment/linux-x64/package.sh | 7 + deployment/osx-x64/build.sh | 7 + deployment/osx-x64/clean.sh | 7 + deployment/osx-x64/package.sh | 7 + deployment/ubuntu-x64/build.sh | 7 + deployment/ubuntu-x64/clean.sh | 7 + deployment/ubuntu-x64/package.sh | 7 + deployment/unraid/docker-templates/README.md | 15 ++ .../unraid/docker-templates/jellyfin.xml | 51 ++++ .../win-generic/build-jellyfin.ps1 | 220 +++++++++--------- .../win-generic/install-jellyfin.ps1 | 0 .../win-generic/install.bat | 0 deployment/win-x64/build.sh | 7 + deployment/win-x64/clean.sh | 7 + deployment/win-x64/package.sh | 9 + deployment/win-x86/build.sh | 7 + deployment/win-x86/clean.sh | 7 + deployment/win-x86/package.sh | 9 + 66 files changed, 605 insertions(+), 217 deletions(-) delete mode 100755 build-deb.sh delete mode 100644 debian/bin/jellyfin-sudoers delete mode 100644 debian/bin/restart.sh delete mode 100644 debian/source/options create mode 100644 deployment/README.md create mode 100644 deployment/build.sh create mode 100644 deployment/clean.sh create mode 100644 deployment/collect_all.sh create mode 100644 deployment/common.build.sh rename Dockerfile.debian_package => deployment/debian-package-x64/Dockerfile (75%) create mode 100644 deployment/debian-package-x64/clean.sh create mode 100644 deployment/debian-package-x64/package.sh rename {debian => deployment/debian-package-x64/pkg-src}/changelog (100%) rename {debian => deployment/debian-package-x64/pkg-src}/compat (100%) rename {debian => deployment/debian-package-x64/pkg-src}/conf/jellyfin (100%) rename {debian => deployment/debian-package-x64/pkg-src}/conf/jellyfin.service.conf (100%) rename {debian => deployment/debian-package-x64/pkg-src}/conf/logging.json (100%) rename {debian => deployment/debian-package-x64/pkg-src}/control (100%) rename {debian => deployment/debian-package-x64/pkg-src}/copyright (100%) rename {debian => deployment/debian-package-x64/pkg-src}/gbp.conf (63%) rename {debian => deployment/debian-package-x64/pkg-src}/install (100%) rename {debian => deployment/debian-package-x64/pkg-src}/jellyfin.init (100%) rename {debian => deployment/debian-package-x64/pkg-src}/jellyfin.service (100%) rename {debian => deployment/debian-package-x64/pkg-src}/jellyfin.upstart (100%) rename {debian => deployment/debian-package-x64/pkg-src}/po/POTFILES.in (100%) rename {debian => deployment/debian-package-x64/pkg-src}/po/templates.pot (100%) rename {debian => deployment/debian-package-x64/pkg-src}/postinst (100%) rename {debian => deployment/debian-package-x64/pkg-src}/postrm (100%) rename {debian => deployment/debian-package-x64/pkg-src}/preinst (100%) rename {debian => deployment/debian-package-x64/pkg-src}/prerm (100%) rename {debian => deployment/debian-package-x64/pkg-src}/rules (67%) mode change 100755 => 100644 rename {debian => deployment/debian-package-x64/pkg-src}/source.lintian-overrides (100%) rename {debian => deployment/debian-package-x64/pkg-src}/source/format (100%) create mode 100644 deployment/debian-package-x64/pkg-src/source/options create mode 100644 deployment/debian-x64/build.sh create mode 100644 deployment/debian-x64/clean.sh create mode 100644 deployment/debian-x64/package.sh rename Dockerfile => deployment/docker/Dockerfile (82%) rename Dockerfile.aarch64 => deployment/docker/Dockerfile.aarch64 (85%) create mode 100644 deployment/docker/build.sh create mode 100644 deployment/framework/build.sh create mode 100644 deployment/framework/clean.sh create mode 100644 deployment/framework/package.sh create mode 100644 deployment/linux-x64/build.sh create mode 100644 deployment/linux-x64/clean.sh create mode 100644 deployment/linux-x64/package.sh create mode 100644 deployment/osx-x64/build.sh create mode 100644 deployment/osx-x64/clean.sh create mode 100644 deployment/osx-x64/package.sh create mode 100644 deployment/ubuntu-x64/build.sh create mode 100644 deployment/ubuntu-x64/clean.sh create mode 100644 deployment/ubuntu-x64/package.sh create mode 100644 deployment/unraid/docker-templates/README.md create mode 100644 deployment/unraid/docker-templates/jellyfin.xml rename build-jellyfin.ps1 => deployment/win-generic/build-jellyfin.ps1 (97%) rename install-jellyfin.ps1 => deployment/win-generic/install-jellyfin.ps1 (100%) rename install.bat => deployment/win-generic/install.bat (100%) create mode 100644 deployment/win-x64/build.sh create mode 100644 deployment/win-x64/clean.sh create mode 100644 deployment/win-x64/package.sh create mode 100644 deployment/win-x86/build.sh create mode 100644 deployment/win-x86/clean.sh create mode 100644 deployment/win-x86/package.sh diff --git a/.dockerignore b/.dockerignore index fc4d8ed26d..54b0aa3a7e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,3 +3,6 @@ Dockerfile CONTRIBUTORS.md README.md +deployment/*/dist +deployment/*/pkg-dist +deployment/collect-dist/ diff --git a/.drone.yml b/.drone.yml index c6d41b5554..98db4884bd 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,4 +9,4 @@ steps: - name: build image: microsoft/dotnet:2-sdk commands: - - dotnet publish --configuration release --output /release + - dotnet publish --configuration release --output /release Jellyfin.Server diff --git a/.gitignore b/.gitignore index 880e63a7f9..b4b928ef27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -!* - .directory ################# @@ -49,6 +47,8 @@ ProgramData-UI*/ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +.vs/ + # User-specific files *.suo *.user @@ -204,7 +204,6 @@ $RECYCLE.BIN/ # Mac crap .DS_Store - ############# ## Python ############# @@ -234,23 +233,32 @@ pip-log.txt #Mr Developer .mr.developer.cfg -/.vs ########## # Rider ########## .idea/ +########## +# Visual Studio Code +########## +.vscode/ + ######################### -# Debian build artifacts +# Build artifacts ######################### -debian/.debhelper/ -debian/*.debhelper -debian/debhelper-build-stamp -debian/files -debian/jellyfin.substvars -debian/jellyfin/ - +# Artifacts for debian-x64 +deployment/debian-x64/pkg-src/.debhelper/ +deployment/debian-x64/pkg-src/*.debhelper +deployment/debian-x64/pkg-src/debhelper-build-stamp +deployment/debian-x64/pkg-src/files +deployment/debian-x64/pkg-src/jellyfin.substvars +deployment/debian-x64/pkg-src/jellyfin/ # Don't ignore the debian/bin folder -!debian/bin/ +!deployment/debian-x64/pkg-src/bin/ + +deployment/**/dist/ +deployment/**/pkg-dist/ +deployment/collect-dist/ + diff --git a/build-deb.sh b/build-deb.sh deleted file mode 100755 index fd14fc17db..0000000000 --- a/build-deb.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh - -# Build a Jellyfin .deb file with Docker on Linux -# Places the output .deb file in the parent directory - -set -o errexit -set -o xtrace -set -o nounset - -package_temporary_dir="`mktemp -d`" -current_user="`whoami`" -image_name="jellyfin-debuild" - -cleanup() { - set +o errexit - docker image rm $image_name --force - rm -rf "$package_temporary_dir" -} -trap cleanup EXIT INT - -docker build . -t "$image_name" -f ./Dockerfile.debian_package -docker run --rm -v "$package_temporary_dir:/temp" "$image_name" cp -r /dist /temp/ -sudo chown -R "$current_user" "$package_temporary_dir" -mv "$package_temporary_dir"/dist/*.deb ../ diff --git a/debian/bin/jellyfin-sudoers b/debian/bin/jellyfin-sudoers deleted file mode 100644 index 4eb91366b4..0000000000 --- a/debian/bin/jellyfin-sudoers +++ /dev/null @@ -1,37 +0,0 @@ -#Allow jellyfin group to start, stop and restart itself -Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart -Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start -Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop -Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin -Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin -Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin -Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart -Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start -Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop - - -%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV -%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV -%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV -%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD -%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD -%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD -%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD -%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD -%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD - -Defaults!RESTARTSERVER_SYSV !requiretty -Defaults!STARTSERVER_SYSV !requiretty -Defaults!STOPSERVER_SYSV !requiretty -Defaults!RESTARTSERVER_SYSTEMD !requiretty -Defaults!STARTSERVER_SYSTEMD !requiretty -Defaults!STOPSERVER_SYSTEMD !requiretty -Defaults!RESTARTSERVER_INITD !requiretty -Defaults!STARTSERVER_INITD !requiretty -Defaults!STOPSERVER_INITD !requiretty - -#Allow the server to mount iso images -%jellyfin ALL=(ALL) NOPASSWD: /bin/mount -%jellyfin ALL=(ALL) NOPASSWD: /bin/umount - -Defaults:%jellyfin !requiretty diff --git a/debian/bin/restart.sh b/debian/bin/restart.sh deleted file mode 100644 index a6f4632ba7..0000000000 --- a/debian/bin/restart.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -NAME=jellyfin - -restart_cmds=("s6-svc -t /var/run/s6/services/${NAME}" \ - "systemctl restart ${NAME}" \ - "service ${NAME} restart" \ - "/etc/init.d/${NAME} restart") - -for restart_cmd in "${restart_cmds[@]}"; do - cmd=$(echo "$restart_cmd" | awk '{print $1}') - cmd_loc=$(command -v ${cmd}) - if [[ -n "$cmd_loc" ]]; then - restart_cmd=$(echo "$restart_cmd" | sed -e "s%${cmd}%${cmd_loc}%") - echo "sleep 2; sudo $restart_cmd > /dev/null 2>&1" | at now > /dev/null 2>&1 - exit 0 - fi -done diff --git a/debian/source/options b/debian/source/options deleted file mode 100644 index 45bef47641..0000000000 --- a/debian/source/options +++ /dev/null @@ -1 +0,0 @@ -tar-ignore = ".git*" diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000000..3400fd8400 --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,8 @@ +# Build scripts + +All `build.sh` and `package.sh` scripts are for *nix platforms (or WSL on Windows 10). + +After running both, check the `*/pkg-dist/` folders for the archives and packages. + +`build_all.sh` will invoke every build and package script. +Use `collect_all.sh` to copy all artifact to one directory for easy uploading. diff --git a/deployment/build.sh b/deployment/build.sh new file mode 100644 index 0000000000..0b5dae84a3 --- /dev/null +++ b/deployment/build.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# Execute all build.sh and package.sh and sign.sh scripts in every folder. In that order. Script should check for artifacts themselves. +echo "Running for platforms '$@'." +for directory in */ ; do + platform=`basename "${directory}"` + if [[ $@ == *"$platform"* || $@ = *"all"* ]]; then + echo "Processing ${platform}" + pushd "$platform" + if [ -f build.sh ]; then + echo ./build.sh + fi + if [ -f package.sh ]; then + echo ./package.sh + fi + if [ -f sign.sh ]; then + echo ./sign.sh + fi + popd + else + echo "Skipping $platform." + fi +done diff --git a/deployment/clean.sh b/deployment/clean.sh new file mode 100644 index 0000000000..7517cf8493 --- /dev/null +++ b/deployment/clean.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +# Execute every clean.sh scripts in every folder. +echo "Running for platforms '$@'." +for directory in */ ; do + platform=`basename "${directory}"` + if [[ $@ == *"$platform"* || $@ = *"all"* ]]; then + echo "Processing ${platform}" + pushd "$platform" + if [ -f clean.sh ]; then + echo ./clean.sh + fi + popd + else + echo "Skipping $platform." + fi +done + +rm -rf ./collect-dist diff --git a/deployment/collect_all.sh b/deployment/collect_all.sh new file mode 100644 index 0000000000..d625002db2 --- /dev/null +++ b/deployment/collect_all.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +source common.build.sh + +VERSION=`get_version ..` + +COLLECT_DIR="./collect-dist" + +mkdir -p ./collect-dist + +DIRS=`find . -type d -name "pkg-dist"` + +while read directory +do + echo "Collecting everything from '$directory'.." + PLATFORM=$(basename "$(dirname "$directory")") + # Copy all artifacts with extensions tar.gz, deb, exe, zip, rpm and add the platform name to resolve any duplicates. + find $directory \( -name "jellyfin*.tar.gz" -o -name "jellyfin*.deb" -o -name "jellyfin*.rpm" -o -name "jellyfin*.zip" -o -name "jellyfin*.exe" \) -exec sh -c 'cp "$1" "'${COLLECT_DIR}'/jellyfin_'${PLATFORM}'_${1#*jellyfin_}"' _ {} \; + +done <<< "${DIRS}" diff --git a/deployment/common.build.sh b/deployment/common.build.sh new file mode 100644 index 0000000000..5996a4ec9d --- /dev/null +++ b/deployment/common.build.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset + +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +DEFAULT_BUILD_CONTEXT="../.." +DEFAULT_ROOT="." +DEFAULT_DOTNETRUNTIME="framework" +DEFAULT_CONFIG="Release" +DEFAULT_OUTPUT_DIR="dist/jellyfin-git" +DEFAULT_PKG_DIR="pkg-dist" +DEFAULT_DOCKERFILE="Dockerfile" +DEFAULT_IMAGE_TAG="jellyfin:"`git rev-parse --abbrev-ref HEAD` + +# Run a build +build_jellyfin() +( + ROOT=${1-$DEFAULT_ROOT} + CONFIG=${2-$DEFAULT_CONFIG} + DOTNETRUNTIME=${3-$DEFAULT_DOTNETRUNTIME} + OUTPUT_DIR=${4-$DEFAULT_OUTPUT_DIR} + + echo -e "${CYAN}Building jellyfin in '${ROOT}' for ${DOTNETRUNTIME} with configuration ${CONFIG} and output directory '${OUTPUT_DIR}'.${NC}" + if [[ $DOTNETRUNTIME == 'framework' ]]; then + dotnet publish "${ROOT}" --configuration "${CONFIG}" --output="${OUTPUT_DIR}" + else + dotnet publish "${ROOT}" --configuration "${CONFIG}" --output="${OUTPUT_DIR}" --self-contained --runtime ${DOTNETRUNTIME} + fi + EXIT_CODE=$? + if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}[DONE] Build jellyfin in '${ROOT}' for ${DOTNETRUNTIME} with configuration ${CONFIG} and output directory '${OUTPUT_DIR}' complete.${NC}" + else + echo -e "${RED}[FAIL] Build jellyfin in '${ROOT}' for ${DOTNETRUNTIME} with configuration ${CONFIG} and output directory '${OUTPUT_DIR}' FAILED.${NC}" + fi +) + +# Run a docker +build_jellyfin_docker() +( + BUILD_CONTEXT=${1-$DEFAULT_BUILD_CONTEXT} + DOCKERFILE=${2-$DEFAULT_DOCKERFILE} + IMAGE_TAG=${3-$DEFAULT_IMAGE_TAG} + + echo -e "${CYAN}Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}'.${NC}" + docker build -t ${IMAGE_TAG} -f ${DOCKERFILE} ${ROOT} + EXIT_CODE=$? + if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}[DONE] Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}' complete.${NC}" + else + echo -e "${RED}[FAIL] Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}' FAILED.${NC}" + fi +) + +# Clean a build +clean_jellyfin() +( + local ROOT=${1-$DEFAULT_ROOT} + local CONFIG=${2-$DEFAULT_CONFIG} + local OUTPUT_DIR=${3-$DEFAULT_OUTPUT_DIR} + local PKG_DIR=${4-$DEFAULT_PKG_DIR} + echo -e "${CYAN}Cleaning jellyfin in '${ROOT}'' with configuration ${CONFIG} and output directory '${OUTPUT_DIR}'.${NC}" + echo -e "${CYAN}Deleting '${OUTPUT_DIR}'${NC}" + rm -rf "$OUTPUT_DIR" + echo -e "${CYAN}Deleting '${PKG_DIR}'${NC}" + rm -rf "$PKG_DIR" + dotnet clean "${ROOT}" -maxcpucount:1 --configuration ${CONFIG} + local EXIT_CODE=$? + if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}[DONE] Clean jellyfin in '${ROOT}' with configuration ${CONFIG} and output directory '${OUTPUT_DIR}' complete.${NC}" + else + echo -e "${RED}[FAIL] Clean jellyfin in '${ROOT}' with configuration ${CONFIG} and output directory '${OUTPUT_DIR}' failed.${NC}" + fi +) + +# Parse the version from the AssemblyVersion +get_version() +( + local ROOT=${1-$DEFAULT_ROOT} + grep "AssemblyVersion" ${ROOT}/SharedVersion.cs | sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/' | sed -E 's/.0$//' +) + +# Packages the output folder into an archive. +package_portable() +( + local ROOT=${1-$DEFAULT_ROOT} + local OUTPUT_DIR=${2-$DEFAULT_OUTPUT_DIR} + local PKG_DIR=${3-$DEFAULT_PKG_DIR} + # Package portable build result + if [ -d ${OUTPUT_DIR} ]; then + echo -e "${CYAN}Packaging build in '${OUTPUT_DIR}' for `basename "${OUTPUT_DIR}"` to '${PKG_DIR}' with root '${ROOT}'.${NC}" + mkdir -p ${PKG_DIR} + tar -zcvf "${PKG_DIR}/`basename "${OUTPUT_DIR}"`.portable.tar.gz" -C "`dirname "${OUTPUT_DIR}"`" "`basename "${OUTPUT_DIR}"`" + local EXIT_CODE=$? + if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}[DONE] Packaging build in '${OUTPUT_DIR}' for `basename "${OUTPUT_DIR}"` to '${PKG_DIR}' with root '${ROOT}' complete.${NC}" + else + echo -e "${RED}[FAIL] Packaging build in '${OUTPUT_DIR}' for `basename "${OUTPUT_DIR}"` to '${PKG_DIR}' with root '${ROOT}' FAILED.${NC}" + fi + else + echo -e "${RED}[FAIL] Build artifacts do not exist for ${OUTPUT_DIR}. Run build.sh first.${NC}" + fi +) + diff --git a/Dockerfile.debian_package b/deployment/debian-package-x64/Dockerfile similarity index 75% rename from Dockerfile.debian_package rename to deployment/debian-package-x64/Dockerfile index c5c631b71a..0de62f72bc 100644 --- a/Dockerfile.debian_package +++ b/deployment/debian-package-x64/Dockerfile @@ -1,4 +1,6 @@ FROM debian:9 +ARG SOURCEDIR=/repo +ENV DEB_BUILD_OPTIONS=noddebs # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current RUN apt-get update \ @@ -11,12 +13,11 @@ RUN apt-get update \ && chown root:root /etc/apt/sources.list.d/microsoft-prod.list \ && apt-get update -WORKDIR /repo +WORKDIR ${SOURCEDIR} COPY . . +COPY ./deployment/debian-x64/pkg-src ./debian -RUN yes|mk-build-deps -i \ - && dpkg-buildpackage -us -uc \ - && mkdir /dist \ - && mv /jellyfin*deb /dist +RUN yes | mk-build-deps -i debian/control \ + && dpkg-buildpackage -us -uc -WORKDIR /dist +WORKDIR / diff --git a/deployment/debian-package-x64/clean.sh b/deployment/debian-package-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/debian-package-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/debian-package-x64/package.sh b/deployment/debian-package-x64/package.sh new file mode 100644 index 0000000000..7909b0a84e --- /dev/null +++ b/deployment/debian-package-x64/package.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +# TODO get the version in the package automatically. And using the changelog to decide the debian package suffix version. + +# Build a Jellyfin .deb file with Docker on Linux +# Places the output .deb file in the parent directory + +package_temporary_dir="`pwd`/pkg-dist-tmp" +output_dir="`pwd`/pkg-dist" +current_user="`whoami`" +image_name="jellyfin-debuild" + +cleanup() { + set +o errexit + docker image rm $image_name --force + rm -rf "$package_temporary_dir" +} +trap cleanup EXIT INT + +docker build ../.. -t "$image_name" -f ./Dockerfile --build-arg SOURCEDIR="/jellyfin-${VERSION}" +mkdir -p "$package_temporary_dir" +mkdir -p "$output_dir" +docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find / -maxdepth 1 -type f -name "jellyfin*" -exec mv {} /temp \;' +chown -R "$current_user" "$package_temporary_dir" +if [ $? -ne 0 ]; then + # Some platforms need this to chown the file properly. (Platforms with native docker, not just the client) + sudo chown -R "$current_user" "$package_temporary_dir" +fi +mv "$package_temporary_dir"/* "$output_dir" diff --git a/debian/changelog b/deployment/debian-package-x64/pkg-src/changelog similarity index 100% rename from debian/changelog rename to deployment/debian-package-x64/pkg-src/changelog diff --git a/debian/compat b/deployment/debian-package-x64/pkg-src/compat similarity index 100% rename from debian/compat rename to deployment/debian-package-x64/pkg-src/compat diff --git a/debian/conf/jellyfin b/deployment/debian-package-x64/pkg-src/conf/jellyfin similarity index 100% rename from debian/conf/jellyfin rename to deployment/debian-package-x64/pkg-src/conf/jellyfin diff --git a/debian/conf/jellyfin.service.conf b/deployment/debian-package-x64/pkg-src/conf/jellyfin.service.conf similarity index 100% rename from debian/conf/jellyfin.service.conf rename to deployment/debian-package-x64/pkg-src/conf/jellyfin.service.conf diff --git a/debian/conf/logging.json b/deployment/debian-package-x64/pkg-src/conf/logging.json similarity index 100% rename from debian/conf/logging.json rename to deployment/debian-package-x64/pkg-src/conf/logging.json diff --git a/debian/control b/deployment/debian-package-x64/pkg-src/control similarity index 100% rename from debian/control rename to deployment/debian-package-x64/pkg-src/control diff --git a/debian/copyright b/deployment/debian-package-x64/pkg-src/copyright similarity index 100% rename from debian/copyright rename to deployment/debian-package-x64/pkg-src/copyright diff --git a/debian/gbp.conf b/deployment/debian-package-x64/pkg-src/gbp.conf similarity index 63% rename from debian/gbp.conf rename to deployment/debian-package-x64/pkg-src/gbp.conf index f131b973c2..60b3d28723 100644 --- a/debian/gbp.conf +++ b/deployment/debian-package-x64/pkg-src/gbp.conf @@ -3,4 +3,4 @@ pristine-tar = False cleaner = fakeroot debian/rules clean [import-orig] -filter = [ ".git*", ".hg*" ] +filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/debian/install b/deployment/debian-package-x64/pkg-src/install similarity index 100% rename from debian/install rename to deployment/debian-package-x64/pkg-src/install diff --git a/debian/jellyfin.init b/deployment/debian-package-x64/pkg-src/jellyfin.init similarity index 100% rename from debian/jellyfin.init rename to deployment/debian-package-x64/pkg-src/jellyfin.init diff --git a/debian/jellyfin.service b/deployment/debian-package-x64/pkg-src/jellyfin.service similarity index 100% rename from debian/jellyfin.service rename to deployment/debian-package-x64/pkg-src/jellyfin.service diff --git a/debian/jellyfin.upstart b/deployment/debian-package-x64/pkg-src/jellyfin.upstart similarity index 100% rename from debian/jellyfin.upstart rename to deployment/debian-package-x64/pkg-src/jellyfin.upstart diff --git a/debian/po/POTFILES.in b/deployment/debian-package-x64/pkg-src/po/POTFILES.in similarity index 100% rename from debian/po/POTFILES.in rename to deployment/debian-package-x64/pkg-src/po/POTFILES.in diff --git a/debian/po/templates.pot b/deployment/debian-package-x64/pkg-src/po/templates.pot similarity index 100% rename from debian/po/templates.pot rename to deployment/debian-package-x64/pkg-src/po/templates.pot diff --git a/debian/postinst b/deployment/debian-package-x64/pkg-src/postinst similarity index 100% rename from debian/postinst rename to deployment/debian-package-x64/pkg-src/postinst diff --git a/debian/postrm b/deployment/debian-package-x64/pkg-src/postrm similarity index 100% rename from debian/postrm rename to deployment/debian-package-x64/pkg-src/postrm diff --git a/debian/preinst b/deployment/debian-package-x64/pkg-src/preinst similarity index 100% rename from debian/preinst rename to deployment/debian-package-x64/pkg-src/preinst diff --git a/debian/prerm b/deployment/debian-package-x64/pkg-src/prerm similarity index 100% rename from debian/prerm rename to deployment/debian-package-x64/pkg-src/prerm diff --git a/debian/rules b/deployment/debian-package-x64/pkg-src/rules old mode 100755 new mode 100644 similarity index 67% rename from debian/rules rename to deployment/debian-package-x64/pkg-src/rules index 10a3a84864..ce98cb8f86 --- a/debian/rules +++ b/deployment/debian-package-x64/pkg-src/rules @@ -2,7 +2,7 @@ CONFIG := Release TERM := xterm SHELL := /bin/bash -DOTNETRUNTIME := linux-x64 +DOTNETRUNTIME := debian-x64 export DH_VERBOSE=1 export DOTNET_CLI_TELEMETRY_OPTOUT=1 @@ -16,8 +16,8 @@ override_dh_auto_test: override_dh_clistrip: override_dh_auto_build: - dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) + dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) Jellyfin.Server override_dh_auto_clean: - dotnet clean -maxcpucount:1 --configuration $(CONFIG) || true + dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true rm -rf '$(CURDIR)/usr' diff --git a/debian/source.lintian-overrides b/deployment/debian-package-x64/pkg-src/source.lintian-overrides similarity index 100% rename from debian/source.lintian-overrides rename to deployment/debian-package-x64/pkg-src/source.lintian-overrides diff --git a/debian/source/format b/deployment/debian-package-x64/pkg-src/source/format similarity index 100% rename from debian/source/format rename to deployment/debian-package-x64/pkg-src/source/format diff --git a/deployment/debian-package-x64/pkg-src/source/options b/deployment/debian-package-x64/pkg-src/source/options new file mode 100644 index 0000000000..17b5373d5e --- /dev/null +++ b/deployment/debian-package-x64/pkg-src/source/options @@ -0,0 +1,11 @@ +tar-ignore='.git*' +tar-ignore='**/.git' +tar-ignore='**/.hg' +tar-ignore='**/.vs' +tar-ignore='**/.vscode' +tar-ignore='deployment' +tar-ignore='**/bin' +tar-ignore='**/obj' +tar-ignore='**/.nuget' +tar-ignore='*.deb' +tar-ignore='ThirdParty' diff --git a/deployment/debian-x64/build.sh b/deployment/debian-x64/build.sh new file mode 100644 index 0000000000..47cfb53270 --- /dev/null +++ b/deployment/debian-x64/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release debian-x64 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/debian-x64/clean.sh b/deployment/debian-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/debian-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/debian-x64/package.sh b/deployment/debian-x64/package.sh new file mode 100644 index 0000000000..13b943ea8f --- /dev/null +++ b/deployment/debian-x64/package.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} diff --git a/Dockerfile b/deployment/docker/Dockerfile similarity index 82% rename from Dockerfile rename to deployment/docker/Dockerfile index 75700e6f52..c32cdcf9b8 100644 --- a/Dockerfile +++ b/deployment/docker/Dockerfile @@ -15,7 +15,7 @@ WORKDIR /repo COPY . . RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ && dotnet clean \ - && dotnet publish --configuration release --output /jellyfin + && dotnet publish --configuration release --output /jellyfin Jellyfin.Server FROM microsoft/dotnet:${DOTNET_VERSION}-runtime @@ -24,5 +24,5 @@ COPY --from=ffmpeg /ffmpeg-bin/* /usr/bin/ EXPOSE 8096 VOLUME /config /media RUN apt update \ - && apt install -y libfontconfig1 # needed for Skia + && apt install -y libfontconfig1 --no-install-recommends # needed for Skia ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config diff --git a/Dockerfile.aarch64 b/deployment/docker/Dockerfile.aarch64 similarity index 85% rename from Dockerfile.aarch64 rename to deployment/docker/Dockerfile.aarch64 index da4acc8412..d1423dda2b 100644 --- a/Dockerfile.aarch64 +++ b/deployment/docker/Dockerfile.aarch64 @@ -6,7 +6,7 @@ COPY . . RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ && find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \ && dotnet clean \ - && dotnet publish --configuration release --output /jellyfin + && dotnet publish --configuration release --output /jellyfin Jellyfin.Server FROM microsoft/dotnet:${DOTNET_VERSION}-runtime COPY --from=builder /jellyfin /jellyfin diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh new file mode 100644 index 0000000000..b75cedc013 --- /dev/null +++ b/deployment/docker/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin_docker ../.. Dockerfile jellyfin:${VERSION} \ No newline at end of file diff --git a/deployment/framework/build.sh b/deployment/framework/build.sh new file mode 100644 index 0000000000..4f2e6363ee --- /dev/null +++ b/deployment/framework/build.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +#Magic word framework will create a non self contained build +build_jellyfin ../../Jellyfin.Server Release framework `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/framework/clean.sh b/deployment/framework/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/framework/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/framework/package.sh b/deployment/framework/package.sh new file mode 100644 index 0000000000..13b943ea8f --- /dev/null +++ b/deployment/framework/package.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/linux-x64/build.sh b/deployment/linux-x64/build.sh new file mode 100644 index 0000000000..1f0fb62d36 --- /dev/null +++ b/deployment/linux-x64/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release linux-x64 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/linux-x64/clean.sh b/deployment/linux-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/linux-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/linux-x64/package.sh b/deployment/linux-x64/package.sh new file mode 100644 index 0000000000..13b943ea8f --- /dev/null +++ b/deployment/linux-x64/package.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/osx-x64/build.sh b/deployment/osx-x64/build.sh new file mode 100644 index 0000000000..d6bfb9f5e3 --- /dev/null +++ b/deployment/osx-x64/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release osx-x64 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/osx-x64/clean.sh b/deployment/osx-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/osx-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/osx-x64/package.sh b/deployment/osx-x64/package.sh new file mode 100644 index 0000000000..13b943ea8f --- /dev/null +++ b/deployment/osx-x64/package.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/ubuntu-x64/build.sh b/deployment/ubuntu-x64/build.sh new file mode 100644 index 0000000000..870bac7805 --- /dev/null +++ b/deployment/ubuntu-x64/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release ubuntu-x64 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/ubuntu-x64/clean.sh b/deployment/ubuntu-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/ubuntu-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/ubuntu-x64/package.sh b/deployment/ubuntu-x64/package.sh new file mode 100644 index 0000000000..13b943ea8f --- /dev/null +++ b/deployment/ubuntu-x64/package.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/unraid/docker-templates/README.md b/deployment/unraid/docker-templates/README.md new file mode 100644 index 0000000000..2c268e8b3e --- /dev/null +++ b/deployment/unraid/docker-templates/README.md @@ -0,0 +1,15 @@ +# docker-templates + +### Installation: + +Open unRaid GUI (at least unRaid 6.5) + +Click on the Docker tab + +Add the following line under "Template Repositories" + +https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates + +Click save than click on Add Container and select jellyfin. + +Adjust to your paths to your liking and off you go! diff --git a/deployment/unraid/docker-templates/jellyfin.xml b/deployment/unraid/docker-templates/jellyfin.xml new file mode 100644 index 0000000000..be11884248 --- /dev/null +++ b/deployment/unraid/docker-templates/jellyfin.xml @@ -0,0 +1,51 @@ + + + https://raw.githubusercontent.com/jellyfin/jellyfin/deployment/unraid/docker-templates/jellyfin.xml + False + MediaApp:Video MediaApp:Music MediaApp:Photos MediaServer:Video MediaServer:Music MediaServer:Photos + JellyFin + + JellyFin is The Free Software Media Browser Converted By Community Applications Always verify this template (and values) against the dockerhub support page for the container!![br][br] + You can add as many mount points as needed for recordings, movies ,etc. [br][br] + [b][span style='color: #E80000;']Directions:[/span][/b][br] + [b]/config[/b] : this is where Jellyfin will store it's databases and configuration.[br][br] + [b]Port[/b] : This is the default port for Jellyfin. (Will add ssl port later)[br][br] + [b]Media[/b] : This is the mounting point of your media. When you access it in Jellyfin it will be /media or whatever you chose for a mount point + [b]Tip:[/b] You can add more volume mappings if you wish Jellyfin has access to it. + + + Jellyfin Server is a home media server built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono and will remain completely free! + + https://www.reddit.com/r/jellyfin/ + https://hub.docker.com/r/jellyfin/jellyfin/ + https://github.com/jellyfin/jellyfin/> + jellyfin/jellyfin + https://jellyfin.media/ + true + false + + host + + + 8096 + 8096 + tcp + + + + + + /mnt/cache/appdata/config + /config + rw + + + /mnt/user + /media + rw + + + http://[IP]:[PORT:8096]/ + https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/emby-icon.png + + diff --git a/build-jellyfin.ps1 b/deployment/win-generic/build-jellyfin.ps1 similarity index 97% rename from build-jellyfin.ps1 rename to deployment/win-generic/build-jellyfin.ps1 index 2247166211..4f0f925256 100644 --- a/build-jellyfin.ps1 +++ b/deployment/win-generic/build-jellyfin.ps1 @@ -1,110 +1,110 @@ -[CmdletBinding()] -param( - [switch]$InstallFFMPEG, - [switch]$InstallNSSM, - [switch]$GenerateZip, - [string]$InstallLocation = "$Env:AppData/Jellyfin-Server/", - [ValidateSet('Debug','Release')][string]$BuildType = 'Release', - [ValidateSet('Quiet','Minimal', 'Normal')][string]$DotNetVerbosity = 'Minimal', - [ValidateSet('win','win7', 'win8','win81','win10')][string]$WindowsVersion = 'win', - [ValidateSet('x64','x86', 'arm', 'arm64')][string]$Architecture = 'x64' -) - -#PowershellCore and *nix check to make determine which temp dir to use. -if(($PSVersionTable.PSEdition -eq 'Core') -and (-not $IsWindows)){ - $TempDir = mktemp -d -}else{ - $TempDir = $env:Temp -} - -function Build-JellyFin { - if(($Architecture -eq 'arm64') -and ($WindowsVersion -ne 'win10')){ - Write-Error "arm64 only supported with Windows10 Version" - exit - } - if(($Architecture -eq 'arm') -and ($WindowsVersion -notin @('win10','win81','win8'))){ - Write-Error "arm only supported with Windows 8 or higher" - exit - } - dotnet publish -c $BuildType -r "$windowsversion-$Architecture" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity -} - -function Install-FFMPEG { - param( - [string]$InstallLocation, - [string]$Architecture - ) - Write-Verbose "Checking Architecture" - if($Architecture -notin @('x86','x64')){ - Write-Warning "No builds available for your selected architecture of $Architecture" - Write-Warning "FFMPEG will not be installed" - }elseif($Architecture -eq 'x64'){ - Write-Verbose "Downloading 64 bit FFMPEG" - Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-4.1-win64-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose - }else{ - Write-Verbose "Downloading 32 bit FFMPEG" - Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-4.1-win32-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose - } - - Expand-Archive "$tempdir/fmmpeg.zip" -DestinationPath "$tempdir/ffmpeg/" | Write-Verbose - if($Architecture -eq 'x64'){ - Write-Verbose "Copying Binaries to Jellyfin location" - Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win64-static/bin" | ForEach-Object { - Copy-Item $_.FullName -Destination $installLocation | Write-Verbose - } - }else{ - Write-Verbose "Copying Binaries to Jellyfin location" - Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win32-static/bin" | ForEach-Object { - Copy-Item $_.FullName -Destination $installLocation | Write-Verbose - } - } - Remove-Item "$tempdir/ffmpeg/" -Recurse -Force -ErrorAction Continue | Write-Verbose - Remove-Item "$tempdir/fmmpeg.zip" -Force -ErrorAction Continue | Write-Verbose -} - -function Install-NSSM { - param( - [string]$InstallLocation, - [string]$Architecture - ) - Write-Verbose "Checking Architecture" - if($Architecture -notin @('x86','x64')){ - Write-Warning "No builds available for your selected architecture of $Architecture" - Write-Warning "NSSM will not be installed" - }else{ - Write-Verbose "Downloading NSSM" - Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -UseBasicParsing -OutFile "$tempdir/nssm.zip" | Write-Verbose - } - - Expand-Archive "$tempdir/nssm.zip" -DestinationPath "$tempdir/nssm/" | Write-Verbose - if($Architecture -eq 'x64'){ - Write-Verbose "Copying Binaries to Jellyfin location" - Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win64" | ForEach-Object { - Copy-Item $_.FullName -Destination $installLocation | Write-Verbose - } - }else{ - Write-Verbose "Copying Binaries to Jellyfin location" - Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win32" | ForEach-Object { - Copy-Item $_.FullName -Destination $installLocation | Write-Verbose - } - } - Remove-Item "$tempdir/nssm/" -Recurse -Force -ErrorAction Continue | Write-Verbose - Remove-Item "$tempdir/nssm.zip" -Force -ErrorAction Continue | Write-Verbose -} - -Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture" -Build-JellyFin -if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){ - Write-Verbose "Starting FFMPEG Install" - Install-FFMPEG $InstallLocation $Architecture -} -if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){ - Write-Verbose "Starting NSSM Install" - Install-NSSM $InstallLocation $Architecture -} -Copy-Item .\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 -Copy-Item .\install.bat $InstallLocation\install.bat -if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){ - Compress-Archive -Path $InstallLocation -DestinationPath "$InstallLocation/jellyfin.zip" -Force -} -Write-Verbose "Finished" +[CmdletBinding()] +param( + [switch]$InstallFFMPEG, + [switch]$InstallNSSM, + [switch]$GenerateZip, + [string]$InstallLocation = "$Env:AppData/Jellyfin-Server/", + [ValidateSet('Debug','Release')][string]$BuildType = 'Release', + [ValidateSet('Quiet','Minimal', 'Normal')][string]$DotNetVerbosity = 'Minimal', + [ValidateSet('win','win7', 'win8','win81','win10')][string]$WindowsVersion = 'win', + [ValidateSet('x64','x86', 'arm', 'arm64')][string]$Architecture = 'x64' +) + +#PowershellCore and *nix check to make determine which temp dir to use. +if(($PSVersionTable.PSEdition -eq 'Core') -and (-not $IsWindows)){ + $TempDir = mktemp -d +}else{ + $TempDir = $env:Temp +} + +function Build-JellyFin { + if(($Architecture -eq 'arm64') -and ($WindowsVersion -ne 'win10')){ + Write-Error "arm64 only supported with Windows10 Version" + exit + } + if(($Architecture -eq 'arm') -and ($WindowsVersion -notin @('win10','win81','win8'))){ + Write-Error "arm only supported with Windows 8 or higher" + exit + } + dotnet publish -c $BuildType -r "$windowsversion-$Architecture" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity +} + +function Install-FFMPEG { + param( + [string]$InstallLocation, + [string]$Architecture + ) + Write-Verbose "Checking Architecture" + if($Architecture -notin @('x86','x64')){ + Write-Warning "No builds available for your selected architecture of $Architecture" + Write-Warning "FFMPEG will not be installed" + }elseif($Architecture -eq 'x64'){ + Write-Verbose "Downloading 64 bit FFMPEG" + Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-4.1-win64-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose + }else{ + Write-Verbose "Downloading 32 bit FFMPEG" + Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-4.1-win32-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose + } + + Expand-Archive "$tempdir/fmmpeg.zip" -DestinationPath "$tempdir/ffmpeg/" | Write-Verbose + if($Architecture -eq 'x64'){ + Write-Verbose "Copying Binaries to Jellyfin location" + Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win64-static/bin" | ForEach-Object { + Copy-Item $_.FullName -Destination $installLocation | Write-Verbose + } + }else{ + Write-Verbose "Copying Binaries to Jellyfin location" + Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win32-static/bin" | ForEach-Object { + Copy-Item $_.FullName -Destination $installLocation | Write-Verbose + } + } + Remove-Item "$tempdir/ffmpeg/" -Recurse -Force -ErrorAction Continue | Write-Verbose + Remove-Item "$tempdir/fmmpeg.zip" -Force -ErrorAction Continue | Write-Verbose +} + +function Install-NSSM { + param( + [string]$InstallLocation, + [string]$Architecture + ) + Write-Verbose "Checking Architecture" + if($Architecture -notin @('x86','x64')){ + Write-Warning "No builds available for your selected architecture of $Architecture" + Write-Warning "NSSM will not be installed" + }else{ + Write-Verbose "Downloading NSSM" + Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -UseBasicParsing -OutFile "$tempdir/nssm.zip" | Write-Verbose + } + + Expand-Archive "$tempdir/nssm.zip" -DestinationPath "$tempdir/nssm/" | Write-Verbose + if($Architecture -eq 'x64'){ + Write-Verbose "Copying Binaries to Jellyfin location" + Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win64" | ForEach-Object { + Copy-Item $_.FullName -Destination $installLocation | Write-Verbose + } + }else{ + Write-Verbose "Copying Binaries to Jellyfin location" + Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win32" | ForEach-Object { + Copy-Item $_.FullName -Destination $installLocation | Write-Verbose + } + } + Remove-Item "$tempdir/nssm/" -Recurse -Force -ErrorAction Continue | Write-Verbose + Remove-Item "$tempdir/nssm.zip" -Force -ErrorAction Continue | Write-Verbose +} + +Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture" +Build-JellyFin +if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){ + Write-Verbose "Starting FFMPEG Install" + Install-FFMPEG $InstallLocation $Architecture +} +if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){ + Write-Verbose "Starting NSSM Install" + Install-NSSM $InstallLocation $Architecture +} +Copy-Item .\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 +Copy-Item .\install.bat $InstallLocation\install.bat +if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){ + Compress-Archive -Path $InstallLocation -DestinationPath "$InstallLocation/jellyfin.zip" -Force +} +Write-Verbose "Finished" diff --git a/install-jellyfin.ps1 b/deployment/win-generic/install-jellyfin.ps1 similarity index 100% rename from install-jellyfin.ps1 rename to deployment/win-generic/install-jellyfin.ps1 diff --git a/install.bat b/deployment/win-generic/install.bat similarity index 100% rename from install.bat rename to deployment/win-generic/install.bat diff --git a/deployment/win-x64/build.sh b/deployment/win-x64/build.sh new file mode 100644 index 0000000000..0b30462038 --- /dev/null +++ b/deployment/win-x64/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release win-x64 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/win-x64/clean.sh b/deployment/win-x64/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/win-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/win-x64/package.sh b/deployment/win-x64/package.sh new file mode 100644 index 0000000000..e8410e8c23 --- /dev/null +++ b/deployment/win-x64/package.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} + +#TODO setup and maybe change above code to produce the Windows native zip format. diff --git a/deployment/win-x86/build.sh b/deployment/win-x86/build.sh new file mode 100644 index 0000000000..610db356a5 --- /dev/null +++ b/deployment/win-x86/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +build_jellyfin ../../Jellyfin.Server Release win-x86 `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/win-x86/clean.sh b/deployment/win-x86/clean.sh new file mode 100644 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/win-x86/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/win-x86/package.sh b/deployment/win-x86/package.sh new file mode 100644 index 0000000000..e8410e8c23 --- /dev/null +++ b/deployment/win-x86/package.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +package_portable ../.. `pwd`/dist/jellyfin_${VERSION} + +#TODO setup and maybe change above code to produce the Windows native zip format. From 8eb2fe1b5874feb6a1379b9c10ab3dff7700eb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 16:15:06 +0100 Subject: [PATCH 13/45] Remove references to Debian package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.override.conf | 7 +++++++ rpm-package/jellyfin.spec | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 rpm-package/jellyfin.override.conf diff --git a/rpm-package/jellyfin.override.conf b/rpm-package/jellyfin.override.conf new file mode 100644 index 0000000000..9764a0621f --- /dev/null +++ b/rpm-package/jellyfin.override.conf @@ -0,0 +1,7 @@ +# Jellyfin systemd configuration options + +# Use this file to override the user or environment file location. + +[Service] +#User = jellyfin +#EnvironmentFile = /etc/default/jellyfin \ No newline at end of file diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 315a542e39..8c1aa37ac5 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -19,6 +19,7 @@ Source4: restart.sh Source5: https://github.com/mono/taglib-sharp/archive/%{taglib_commit}/taglib-sharp-%{taglib_shortcommit}.tar.gz Source6: update-db.sh Source7: jellyfin-firewalld.xml +Source8: jellyfin.override.conf %{?systemd_requires} BuildRequires: systemd @@ -61,8 +62,8 @@ export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime linux-x64 %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE -%{__install} -D -m 0644 debian/conf/jellyfin.service.conf %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf -%{__install} -D -m 0644 debian/conf/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json +%{__install} -D -m 0644 %{SOURCE8} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json %{__mkdir} -p %{buildroot}%{_bindir} tee %{buildroot}%{_bindir}/jellyfin << EOF #!/bin/sh From cb328e4b6fcf39f4c32cabbe9ab165d52b294758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 16:42:26 +0100 Subject: [PATCH 14/45] Remove DB migration script. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 6 ++---- rpm-package/update-db.sh | 12 ------------ 2 files changed, 2 insertions(+), 16 deletions(-) delete mode 100755 rpm-package/update-db.sh diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 8c1aa37ac5..b93f8c8182 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -17,9 +17,8 @@ Source2: jellyfin.env Source3: jellyfin.sudoers Source4: restart.sh Source5: https://github.com/mono/taglib-sharp/archive/%{taglib_commit}/taglib-sharp-%{taglib_shortcommit}.tar.gz -Source6: update-db.sh +Source6: jellyfin.override.conf Source7: jellyfin-firewalld.xml -Source8: jellyfin.override.conf %{?systemd_requires} BuildRequires: systemd @@ -62,7 +61,7 @@ export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime linux-x64 %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE -%{__install} -D -m 0644 %{SOURCE8} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__install} -D -m 0644 %{SOURCE6} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json %{__mkdir} -p %{buildroot}%{_bindir} tee %{buildroot}%{_bindir}/jellyfin << EOF @@ -77,7 +76,6 @@ EOF %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers %{__install} -D -m 0750 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh -%{__install} -D -m 0755 %{SOURCE6} %{buildroot}%{_datadir}/%{name}/update-db-paths.sh %{__install} -D -m 0755 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml %files diff --git a/rpm-package/update-db.sh b/rpm-package/update-db.sh deleted file mode 100755 index 92c13cb8a9..0000000000 --- a/rpm-package/update-db.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -embypath=${2:-/var/lib/emby-server} -jellyfinpath=${3:-/var/lib/jellyfin} -db=${1:-${jellyfinpath}/data/library.db} -sqlite3 ${db} << SQL -UPDATE Chapters2 -SET ImagePath=REPLACE(ImagePath, '${embypath}', '${jellyfinpath}'); -UPDATE TypedBaseItems -SET Path=REPLACE(Path, '${embypath}', '${jellyfinpath}'); -UPDATE TypedBaseItems -SET data=REPLACE(data, '${embypath}', '${jellyfinpath}'); -SQL From fa01c4f02e9c6ecc459eb719ecc96e9190cbe833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 16:44:18 +0100 Subject: [PATCH 15/45] Remove DB migration script also from %files. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index b93f8c8182..f5b2b4b2af 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -90,7 +90,6 @@ EOF %attr(755,root,root) %{_libdir}/%{name}/jellyfin %attr(644,root,root) %{_libdir}/%{name}/sosdocsunix.txt %attr(644,root,root) %{_unitdir}/%{name}.service -%attr(755,root,root) %{_datadir}/%{name}/update-db-paths.sh %attr(755,root,root) %{_libexecdir}/%{name}/restart.sh %attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml %attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} From 40e509588e4fee3ab1e532c09dab839926c2b5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 16:58:41 +0100 Subject: [PATCH 16/45] Remove explicit permissions for files who don't need them. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index f5b2b4b2af..9b16f13abf 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -75,23 +75,23 @@ EOF %{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers -%{__install} -D -m 0750 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh +%{__install} -D -m 0755 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh %{__install} -D -m 0755 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml %files %{_libdir}/%{name}/dashboard-ui/* %attr(755,root,root) %{_bindir}/%{name} -%attr(644,root,root) %{_libdir}/%{name}/*.json -%attr(644,root,root) %{_libdir}/%{name}/*.pdb -%attr(755,root,root) %{_libdir}/%{name}/*.dll -%attr(755,root,root) %{_libdir}/%{name}/*.so -%attr(755,root,root) %{_libdir}/%{name}/*.a -%attr(755,root,root) %{_libdir}/%{name}/createdump -%attr(755,root,root) %{_libdir}/%{name}/jellyfin -%attr(644,root,root) %{_libdir}/%{name}/sosdocsunix.txt -%attr(644,root,root) %{_unitdir}/%{name}.service -%attr(755,root,root) %{_libexecdir}/%{name}/restart.sh -%attr(644,root,root) %{_prefix}/lib/firewalld/service/%{name}.xml +%{_libdir}/%{name}/*.json +%{_libdir}/%{name}/*.pdb +%{_libdir}/%{name}/*.dll +%{_libdir}/%{name}/*.so +%{_libdir}/%{name}/*.a +%{_libdir}/%{name}/createdump +%{_libdir}/%{name}/jellyfin +%{_libdir}/%{name}/sosdocsunix.txt +%{_unitdir}/%{name}.service +%{_libexecdir}/%{name}/restart.sh +%{_prefix}/lib/firewalld/service/%{name}.xml %attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} %config %{_sysconfdir}/sysconfig/%{name} %config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers From b6c0e5d4720e71165259f5d6788dd239abfc5dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 17:01:22 +0100 Subject: [PATCH 17/45] Also remove DB mirgration part from README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/rpm-package/README.md b/rpm-package/README.md index 5944f9e9b0..1449b54ccf 100644 --- a/rpm-package/README.md +++ b/rpm-package/README.md @@ -26,15 +26,6 @@ To allow Jellyfin to mount/umonut ISO files uncomment these two lines in `/etc/s # %jellyfin ALL=(ALL) NOPASSWD: /bin/umount ``` -## Database patching - -You may need to install sqlite since CentOS has no `Recommends:` with `yum install sqlite`. -To fix the paths in the emby database for a migration to jellyfin run the script: -```shell -/usr/share/jellyfin/update-db-paths.sh -``` -PS: Please **backup your emby database beforehand**. - ## Building with dotnet Jellyfin is build with `--self-contained` so no dotnet required for runtime. From 101f47b6d40a7ce6150a29685f047221001314ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 17:02:52 +0100 Subject: [PATCH 18/45] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpm-package/README.md b/rpm-package/README.md index 1449b54ccf..7ed6f7efc6 100644 --- a/rpm-package/README.md +++ b/rpm-package/README.md @@ -20,7 +20,7 @@ $ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpm ## ISO mounting -To allow Jellyfin to mount/umonut ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` +To allow Jellyfin to mount/umount ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` ``` # %jellyfin ALL=(ALL) NOPASSWD: /bin/mount # %jellyfin ALL=(ALL) NOPASSWD: /bin/umount From 7bda21295830d100359182ac4fae0b40d4bbede3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 17:05:28 +0100 Subject: [PATCH 19/45] Bump spec version to 10.0.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Büttner --- rpm-package/jellyfin.spec | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 9b16f13abf..30631283dc 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -1,12 +1,12 @@ %global debug_package %{nil} # jellyfin tag to package -%global gittag v10.0.0 +%global gittag v10.0.2 # Taglib-sharp commit of the submodule since github archive doesn't include submodules %global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 %global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) Name: jellyfin -Version: 10.0.0 +Version: 10.0.2 Release: 1%{?dist} Summary: The Free Software Media Browser. License: GPLv2 @@ -76,7 +76,7 @@ EOF %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers %{__install} -D -m 0755 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh -%{__install} -D -m 0755 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml +%{__install} -D -m 0644 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml %files %{_libdir}/%{name}/dashboard-ui/* @@ -142,9 +142,5 @@ fi %systemd_postun_with_restart jellyfin.service %changelog -* Tue Jan 08 2019 Thomas Büttner - 10.0.0-1 -- The first Jellyfin release under our new versioning scheme -- Numerous bugfixes and code readability improvements -- Updated logging configuration, including flag for it and configdir -- Updated theming including logo -- Dozens of other improvements as documented in GitHub pull request 419 +* Fri Jan 11 2019 Thomas Büttner - 10.0.2-1 +- TODO Changelog for 10.0.2 From 5ffea816a1a428ac7480e114af96d8519cd198fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 17:43:42 +0100 Subject: [PATCH 20/45] Change EnvironmentFile path to /etc/sysconfig --- rpm-package/jellyfin.override.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpm-package/jellyfin.override.conf b/rpm-package/jellyfin.override.conf index 9764a0621f..8652450bb4 100644 --- a/rpm-package/jellyfin.override.conf +++ b/rpm-package/jellyfin.override.conf @@ -4,4 +4,4 @@ [Service] #User = jellyfin -#EnvironmentFile = /etc/default/jellyfin \ No newline at end of file +#EnvironmentFile = /etc/sysconfig/jellyfin From 559ecb2afcf82e685bd6393b3429ea988a518f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 20:06:08 +0100 Subject: [PATCH 21/45] Fix permissions for the main binary. The /usr/lib64/jellyfin/jellyfin binary has 0744 permission after build by dotnet so set explicit permission to 0755 in .spec --- rpm-package/jellyfin.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 30631283dc..4448683cfa 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -87,7 +87,8 @@ EOF %{_libdir}/%{name}/*.so %{_libdir}/%{name}/*.a %{_libdir}/%{name}/createdump -%{_libdir}/%{name}/jellyfin +# Needs 755 else only root can run it since binary build by dotnet is 744 +%attr(755,root,root) %{_libdir}/%{name}/jellyfin %{_libdir}/%{name}/sosdocsunix.txt %{_unitdir}/%{name}.service %{_libexecdir}/%{name}/restart.sh From 3f9b0058857149a1c299b65117e13ea82b2bc1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=BCttner?= Date: Fri, 11 Jan 2019 20:21:40 +0100 Subject: [PATCH 22/45] Fix typo --- rpm-package/jellyfin.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpm-package/jellyfin.spec b/rpm-package/jellyfin.spec index 4448683cfa..ff5725f871 100644 --- a/rpm-package/jellyfin.spec +++ b/rpm-package/jellyfin.spec @@ -87,7 +87,7 @@ EOF %{_libdir}/%{name}/*.so %{_libdir}/%{name}/*.a %{_libdir}/%{name}/createdump -# Needs 755 else only root can run it since binary build by dotnet is 744 +# Needs 755 else only root can run it since binary build by dotnet is 722 %attr(755,root,root) %{_libdir}/%{name}/jellyfin %{_libdir}/%{name}/sosdocsunix.txt %{_unitdir}/%{name}.service From 21098eb86164a759c640a8936784305cfa3e4fd2 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Fri, 11 Jan 2019 23:22:50 +0100 Subject: [PATCH 23/45] Moved rpm package and edited the package slightly, to build the project correctly. --- deployment/debian-package-x64/Dockerfile | 2 +- .../fedora-package-x64/Dockerfile | 6 +-- deployment/fedora-package-x64/package.sh | 37 +++++++++++++++++++ .../fedora-package-x64/pkg-src}/.gitignore | 0 .../fedora-package-x64/pkg-src}/README.md | 0 .../pkg-src}/jellyfin-firewalld.xml | 0 .../fedora-package-x64/pkg-src}/jellyfin.env | 0 .../pkg-src}/jellyfin.override.conf | 0 .../pkg-src}/jellyfin.service | 0 .../fedora-package-x64/pkg-src}/jellyfin.spec | 4 +- .../pkg-src}/jellyfin.sudoers | 0 .../fedora-package-x64/pkg-src}/restart.sh | 0 rpm-package/build-fedora-rpm.sh | 24 ------------ 13 files changed, 42 insertions(+), 31 deletions(-) rename rpm-package/Dockerfile.fedora_package => deployment/fedora-package-x64/Dockerfile (70%) create mode 100644 deployment/fedora-package-x64/package.sh rename {rpm-package => deployment/fedora-package-x64/pkg-src}/.gitignore (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/README.md (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin-firewalld.xml (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin.env (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin.override.conf (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin.service (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin.spec (97%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/jellyfin.sudoers (100%) rename {rpm-package => deployment/fedora-package-x64/pkg-src}/restart.sh (100%) mode change 100755 => 100644 delete mode 100755 rpm-package/build-fedora-rpm.sh diff --git a/deployment/debian-package-x64/Dockerfile b/deployment/debian-package-x64/Dockerfile index 0de62f72bc..2afe6c1d37 100644 --- a/deployment/debian-package-x64/Dockerfile +++ b/deployment/debian-package-x64/Dockerfile @@ -15,7 +15,7 @@ RUN apt-get update \ WORKDIR ${SOURCEDIR} COPY . . -COPY ./deployment/debian-x64/pkg-src ./debian +COPY ./deployment/debian-package-x64/pkg-src ./debian RUN yes | mk-build-deps -i debian/control \ && dpkg-buildpackage -us -uc diff --git a/rpm-package/Dockerfile.fedora_package b/deployment/fedora-package-x64/Dockerfile similarity index 70% rename from rpm-package/Dockerfile.fedora_package rename to deployment/fedora-package-x64/Dockerfile index 35650106d1..64367d1276 100644 --- a/rpm-package/Dockerfile.fedora_package +++ b/deployment/fedora-package-x64/Dockerfile @@ -6,12 +6,10 @@ RUN mkdir /build && \ rpmdev-setuptree WORKDIR /build/rpmbuild -COPY jellyfin.spec SPECS +COPY ./deployment/fedora-package-x64/pkg-src/jellyfin.spec SPECS COPY . SOURCES RUN spectool -g -R SPECS/jellyfin.spec && \ rpmbuild -bs SPECS/jellyfin.spec && \ dnf build-dep -y SRPMS/jellyfin-*.src.rpm && \ - rpmbuild -bb SPECS/jellyfin.spec && \ - mkdir /jellyfin && \ - find . -name 'jellyfin-*.rpm' -print -exec cp {} /jellyfin \; \ No newline at end of file + rpmbuild -bb SPECS/jellyfin.spec; \ No newline at end of file diff --git a/deployment/fedora-package-x64/package.sh b/deployment/fedora-package-x64/package.sh new file mode 100644 index 0000000000..6f18b8cc3d --- /dev/null +++ b/deployment/fedora-package-x64/package.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +source ../common.build.sh + +VERSION=`get_version ../..` + +# TODO get the version in the package automatically. And using the changelog to decide the debian package suffix version. + +# Build a Jellyfin .rpm file with Docker on Linux +# Places the output .rpm file in the parent directory + +set -o errexit +set -o xtrace +set -o nounset + +package_temporary_dir="`pwd`/pkg-dist-tmp" +output_dir="`pwd`/pkg-dist" +current_user="`whoami`" +image_name="jellyfin-rpmbuild" + +cleanup() { + set +o errexit + docker image rm $image_name --force + rm -rf "$package_temporary_dir" +} +trap cleanup EXIT INT + +docker build ../.. -t "$image_name" -f ./Dockerfile.fedora_package +mkdir -p "$package_temporary_dir" +mkdir -p "$output_dir" +docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find / -maxdepth 1 -type f -name "jellyfin*" -exec mv {} /temp \;' +chown -R "$current_user" "$package_temporary_dir" +if [ $? -ne 0 ]; then + # Some platforms need this to chown the file properly. (Platforms with native docker, not just the client) + sudo chown -R "$current_user" "$package_temporary_dir" +fi +mv "$package_temporary_dir"/* "$output_dir" diff --git a/rpm-package/.gitignore b/deployment/fedora-package-x64/pkg-src/.gitignore similarity index 100% rename from rpm-package/.gitignore rename to deployment/fedora-package-x64/pkg-src/.gitignore diff --git a/rpm-package/README.md b/deployment/fedora-package-x64/pkg-src/README.md similarity index 100% rename from rpm-package/README.md rename to deployment/fedora-package-x64/pkg-src/README.md diff --git a/rpm-package/jellyfin-firewalld.xml b/deployment/fedora-package-x64/pkg-src/jellyfin-firewalld.xml similarity index 100% rename from rpm-package/jellyfin-firewalld.xml rename to deployment/fedora-package-x64/pkg-src/jellyfin-firewalld.xml diff --git a/rpm-package/jellyfin.env b/deployment/fedora-package-x64/pkg-src/jellyfin.env similarity index 100% rename from rpm-package/jellyfin.env rename to deployment/fedora-package-x64/pkg-src/jellyfin.env diff --git a/rpm-package/jellyfin.override.conf b/deployment/fedora-package-x64/pkg-src/jellyfin.override.conf similarity index 100% rename from rpm-package/jellyfin.override.conf rename to deployment/fedora-package-x64/pkg-src/jellyfin.override.conf diff --git a/rpm-package/jellyfin.service b/deployment/fedora-package-x64/pkg-src/jellyfin.service similarity index 100% rename from rpm-package/jellyfin.service rename to deployment/fedora-package-x64/pkg-src/jellyfin.service diff --git a/rpm-package/jellyfin.spec b/deployment/fedora-package-x64/pkg-src/jellyfin.spec similarity index 97% rename from rpm-package/jellyfin.spec rename to deployment/fedora-package-x64/pkg-src/jellyfin.spec index ff5725f871..b008ec8347 100644 --- a/rpm-package/jellyfin.spec +++ b/deployment/fedora-package-x64/pkg-src/jellyfin.spec @@ -54,12 +54,12 @@ popd %build export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -dotnet build --runtime linux-x64 +dotnet build --runtime fedora-x64 Jellyfin.Server %install export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime linux-x64 +dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime fedora-x64 Jellyfin.Server %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE %{__install} -D -m 0644 %{SOURCE6} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json diff --git a/rpm-package/jellyfin.sudoers b/deployment/fedora-package-x64/pkg-src/jellyfin.sudoers similarity index 100% rename from rpm-package/jellyfin.sudoers rename to deployment/fedora-package-x64/pkg-src/jellyfin.sudoers diff --git a/rpm-package/restart.sh b/deployment/fedora-package-x64/pkg-src/restart.sh old mode 100755 new mode 100644 similarity index 100% rename from rpm-package/restart.sh rename to deployment/fedora-package-x64/pkg-src/restart.sh diff --git a/rpm-package/build-fedora-rpm.sh b/rpm-package/build-fedora-rpm.sh deleted file mode 100755 index 87c94e0812..0000000000 --- a/rpm-package/build-fedora-rpm.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh - -# Build a Jellyfin .rpm file with Docker on Linux -# Places the output .rpm file in the parent directory - -set -o errexit -set -o xtrace -set -o nounset - -package_temporary_dir="`mktemp -d`" -current_user="`whoami`" -image_name="jellyfin-rpmbuild" - -cleanup() { - set +o errexit - docker image rm $image_name --force - rm -rf "$package_temporary_dir" -} -trap cleanup EXIT INT - -docker build . -t "$image_name" -f ./Dockerfile.fedora_package -docker run --rm -v "$package_temporary_dir:/temp" "$image_name" cp -r /jellyfin /temp/ -sudo chown -R "$current_user" "$package_temporary_dir" -mv "$package_temporary_dir"/jellyfin/*.rpm ../../ From 0bb08b3f8d530525b19c7967bcbd1d7ab81e91ee Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Fri, 11 Jan 2019 23:35:14 +0100 Subject: [PATCH 24/45] Added debian bin folder. --- .gitignore | 14 +++---- .../pkg-src/bin/jellyfin-sudoers | 37 +++++++++++++++++++ .../debian-package-x64/pkg-src/bin/restart.sh | 18 +++++++++ 3 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 deployment/debian-package-x64/pkg-src/bin/jellyfin-sudoers create mode 100644 deployment/debian-package-x64/pkg-src/bin/restart.sh diff --git a/.gitignore b/.gitignore index b4b928ef27..a719ec32b1 100644 --- a/.gitignore +++ b/.gitignore @@ -249,14 +249,14 @@ pip-log.txt ######################### # Artifacts for debian-x64 -deployment/debian-x64/pkg-src/.debhelper/ -deployment/debian-x64/pkg-src/*.debhelper -deployment/debian-x64/pkg-src/debhelper-build-stamp -deployment/debian-x64/pkg-src/files -deployment/debian-x64/pkg-src/jellyfin.substvars -deployment/debian-x64/pkg-src/jellyfin/ +deployment/debian-package-x64/pkg-src/.debhelper/ +deployment/debian-package-x64/pkg-src/*.debhelper +deployment/debian-package-x64/pkg-src/debhelper-build-stamp +deployment/debian-package-x64/pkg-src/files +deployment/debian-package-x64/pkg-src/jellyfin.substvars +deployment/debian-package-x64/pkg-src/jellyfin/ # Don't ignore the debian/bin folder -!deployment/debian-x64/pkg-src/bin/ +!deployment/debian-package-x64/pkg-src/bin/ deployment/**/dist/ deployment/**/pkg-dist/ diff --git a/deployment/debian-package-x64/pkg-src/bin/jellyfin-sudoers b/deployment/debian-package-x64/pkg-src/bin/jellyfin-sudoers new file mode 100644 index 0000000000..4eb91366b4 --- /dev/null +++ b/deployment/debian-package-x64/pkg-src/bin/jellyfin-sudoers @@ -0,0 +1,37 @@ +#Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart +Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start +Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin +Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart +Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start +Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop + + +%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV +%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV +%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV +%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD +%jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD +%jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD +%jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD + +Defaults!RESTARTSERVER_SYSV !requiretty +Defaults!STARTSERVER_SYSV !requiretty +Defaults!STOPSERVER_SYSV !requiretty +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty +Defaults!RESTARTSERVER_INITD !requiretty +Defaults!STARTSERVER_INITD !requiretty +Defaults!STOPSERVER_INITD !requiretty + +#Allow the server to mount iso images +%jellyfin ALL=(ALL) NOPASSWD: /bin/mount +%jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:%jellyfin !requiretty diff --git a/deployment/debian-package-x64/pkg-src/bin/restart.sh b/deployment/debian-package-x64/pkg-src/bin/restart.sh new file mode 100644 index 0000000000..a6f4632ba7 --- /dev/null +++ b/deployment/debian-package-x64/pkg-src/bin/restart.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +NAME=jellyfin + +restart_cmds=("s6-svc -t /var/run/s6/services/${NAME}" \ + "systemctl restart ${NAME}" \ + "service ${NAME} restart" \ + "/etc/init.d/${NAME} restart") + +for restart_cmd in "${restart_cmds[@]}"; do + cmd=$(echo "$restart_cmd" | awk '{print $1}') + cmd_loc=$(command -v ${cmd}) + if [[ -n "$cmd_loc" ]]; then + restart_cmd=$(echo "$restart_cmd" | sed -e "s%${cmd}%${cmd_loc}%") + echo "sleep 2; sudo $restart_cmd > /dev/null 2>&1" | at now > /dev/null 2>&1 + exit 0 + fi +done From 74507099ad2239e33e22486d392167eada57624f Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 01:49:46 +0100 Subject: [PATCH 25/45] Added git submodules command. Converted RPM to build from local tree. Added all the execution bits to the build scripts. --- .gitignore | 1 + deployment/build.sh | 13 ++++- deployment/clean.sh | 0 deployment/collect_all.sh | 2 +- deployment/common.build.sh | 0 deployment/debian-package-x64/clean.sh | 0 deployment/debian-package-x64/package.sh | 0 deployment/debian-x64/build.sh | 0 deployment/debian-x64/clean.sh | 0 deployment/debian-x64/package.sh | 0 deployment/docker/build.sh | 0 deployment/fedora-package-x64/Dockerfile | 2 +- deployment/fedora-package-x64/clean.sh | 7 +++ deployment/fedora-package-x64/package.sh | 57 +++++++++++++++++-- .../fedora-package-x64/pkg-src/jellyfin.spec | 27 +++------ deployment/framework/build.sh | 0 deployment/framework/clean.sh | 0 deployment/framework/package.sh | 0 deployment/linux-x64/build.sh | 0 deployment/linux-x64/clean.sh | 0 deployment/linux-x64/package.sh | 0 deployment/osx-x64/build.sh | 0 deployment/osx-x64/clean.sh | 0 deployment/osx-x64/package.sh | 0 deployment/ubuntu-x64/build.sh | 0 deployment/ubuntu-x64/clean.sh | 0 deployment/ubuntu-x64/package.sh | 0 deployment/win-x64/build.sh | 0 deployment/win-x64/clean.sh | 0 deployment/win-x64/package.sh | 0 deployment/win-x86/build.sh | 0 deployment/win-x86/clean.sh | 0 deployment/win-x86/package.sh | 0 33 files changed, 82 insertions(+), 27 deletions(-) mode change 100644 => 100755 deployment/build.sh mode change 100644 => 100755 deployment/clean.sh mode change 100644 => 100755 deployment/collect_all.sh mode change 100644 => 100755 deployment/common.build.sh mode change 100644 => 100755 deployment/debian-package-x64/clean.sh mode change 100644 => 100755 deployment/debian-package-x64/package.sh mode change 100644 => 100755 deployment/debian-x64/build.sh mode change 100644 => 100755 deployment/debian-x64/clean.sh mode change 100644 => 100755 deployment/debian-x64/package.sh mode change 100644 => 100755 deployment/docker/build.sh create mode 100755 deployment/fedora-package-x64/clean.sh mode change 100644 => 100755 deployment/fedora-package-x64/package.sh mode change 100644 => 100755 deployment/framework/build.sh mode change 100644 => 100755 deployment/framework/clean.sh mode change 100644 => 100755 deployment/framework/package.sh mode change 100644 => 100755 deployment/linux-x64/build.sh mode change 100644 => 100755 deployment/linux-x64/clean.sh mode change 100644 => 100755 deployment/linux-x64/package.sh mode change 100644 => 100755 deployment/osx-x64/build.sh mode change 100644 => 100755 deployment/osx-x64/clean.sh mode change 100644 => 100755 deployment/osx-x64/package.sh mode change 100644 => 100755 deployment/ubuntu-x64/build.sh mode change 100644 => 100755 deployment/ubuntu-x64/clean.sh mode change 100644 => 100755 deployment/ubuntu-x64/package.sh mode change 100644 => 100755 deployment/win-x64/build.sh mode change 100644 => 100755 deployment/win-x64/clean.sh mode change 100644 => 100755 deployment/win-x64/package.sh mode change 100644 => 100755 deployment/win-x86/build.sh mode change 100644 => 100755 deployment/win-x86/clean.sh mode change 100644 => 100755 deployment/win-x86/package.sh diff --git a/.gitignore b/.gitignore index a719ec32b1..ec683f38f6 100644 --- a/.gitignore +++ b/.gitignore @@ -260,5 +260,6 @@ deployment/debian-package-x64/pkg-src/jellyfin/ deployment/**/dist/ deployment/**/pkg-dist/ +deployment/**/pkg-dist-tmp/ deployment/collect-dist/ diff --git a/deployment/build.sh b/deployment/build.sh old mode 100644 new mode 100755 index 0b5dae84a3..5628d3ad52 --- a/deployment/build.sh +++ b/deployment/build.sh @@ -1,5 +1,12 @@ #!/usr/bin/env bash +git submodule update --init --recursive + +pushd ../Jellyfin.Versioning +#TODO Uncomment the next line with PR is merged. +#./update-version +popd + # Execute all build.sh and package.sh and sign.sh scripts in every folder. In that order. Script should check for artifacts themselves. echo "Running for platforms '$@'." for directory in */ ; do @@ -8,13 +15,13 @@ for directory in */ ; do echo "Processing ${platform}" pushd "$platform" if [ -f build.sh ]; then - echo ./build.sh + ./build.sh fi if [ -f package.sh ]; then - echo ./package.sh + ./package.sh fi if [ -f sign.sh ]; then - echo ./sign.sh + ./sign.sh fi popd else diff --git a/deployment/clean.sh b/deployment/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/collect_all.sh b/deployment/collect_all.sh old mode 100644 new mode 100755 index d625002db2..69babe55e1 --- a/deployment/collect_all.sh +++ b/deployment/collect_all.sh @@ -15,6 +15,6 @@ do echo "Collecting everything from '$directory'.." PLATFORM=$(basename "$(dirname "$directory")") # Copy all artifacts with extensions tar.gz, deb, exe, zip, rpm and add the platform name to resolve any duplicates. - find $directory \( -name "jellyfin*.tar.gz" -o -name "jellyfin*.deb" -o -name "jellyfin*.rpm" -o -name "jellyfin*.zip" -o -name "jellyfin*.exe" \) -exec sh -c 'cp "$1" "'${COLLECT_DIR}'/jellyfin_'${PLATFORM}'_${1#*jellyfin_}"' _ {} \; + find $directory \( -name "jellyfin*.tar.gz" -o -name "jellyfin*.deb" -o -name "jellyfin*.rpm" -o -name "jellyfin*.zip" -o -name "jellyfin*.exe" \) -exec sh -c 'cp "$1" "'${COLLECT_DIR}'/jellyfin_'${PLATFORM}'_${1#*jellyfin}"' _ {} \; done <<< "${DIRS}" diff --git a/deployment/common.build.sh b/deployment/common.build.sh old mode 100644 new mode 100755 diff --git a/deployment/debian-package-x64/clean.sh b/deployment/debian-package-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/debian-package-x64/package.sh b/deployment/debian-package-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/debian-x64/build.sh b/deployment/debian-x64/build.sh old mode 100644 new mode 100755 diff --git a/deployment/debian-x64/clean.sh b/deployment/debian-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/debian-x64/package.sh b/deployment/debian-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh old mode 100644 new mode 100755 diff --git a/deployment/fedora-package-x64/Dockerfile b/deployment/fedora-package-x64/Dockerfile index 64367d1276..e5deac29fb 100644 --- a/deployment/fedora-package-x64/Dockerfile +++ b/deployment/fedora-package-x64/Dockerfile @@ -7,7 +7,7 @@ RUN mkdir /build && \ WORKDIR /build/rpmbuild COPY ./deployment/fedora-package-x64/pkg-src/jellyfin.spec SPECS -COPY . SOURCES +COPY ./deployment/fedora-package-x64/pkg-src/ SOURCES RUN spectool -g -R SPECS/jellyfin.spec && \ rpmbuild -bs SPECS/jellyfin.spec && \ diff --git a/deployment/fedora-package-x64/clean.sh b/deployment/fedora-package-x64/clean.sh new file mode 100755 index 0000000000..3df2d7796e --- /dev/null +++ b/deployment/fedora-package-x64/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +clean_jellyfin ../.. Release `pwd`/dist/jellyfin_${VERSION} diff --git a/deployment/fedora-package-x64/package.sh b/deployment/fedora-package-x64/package.sh old mode 100644 new mode 100755 index 6f18b8cc3d..56a120844f --- a/deployment/fedora-package-x64/package.sh +++ b/deployment/fedora-package-x64/package.sh @@ -15,6 +15,7 @@ set -o nounset package_temporary_dir="`pwd`/pkg-dist-tmp" output_dir="`pwd`/pkg-dist" +pkg_src_dir="`pwd`/pkg-src" current_user="`whoami`" image_name="jellyfin-rpmbuild" @@ -22,16 +23,64 @@ cleanup() { set +o errexit docker image rm $image_name --force rm -rf "$package_temporary_dir" + rm -rf "$pkg_src_dir/jellyfin-${VERSION}.tar.gz" } trap cleanup EXIT INT - -docker build ../.. -t "$image_name" -f ./Dockerfile.fedora_package +GNU_TAR=1 mkdir -p "$package_temporary_dir" +echo "Bundling all sources for RPM build." +tar \ +--transform "s,^\.,jellyfin-${VERSION}" \ +--exclude='.git*' \ +--exclude='**/.git' \ +--exclude='**/.hg' \ +--exclude='**/.vs' \ +--exclude='**/.vscode' \ +--exclude='deployment' \ +--exclude='**/bin' \ +--exclude='**/obj' \ +--exclude='**/.nuget' \ +--exclude='*.deb' \ +--exclude='*.rpm' \ +-Jcvf \ +"$package_temporary_dir/jellyfin-${VERSION}.tar.xz" \ +-C "../.." \ +./ || true && GNU_TAR=0 + +if [ $GNU_TAR -eq 0 ]; then + echo "The installed tar binary did not support --transform. Using workaround." + mkdir -p "$package_temporary_dir/jellyfin-${VERSION}" + # Not GNU tar + tar \ + --exclude='.git*' \ + --exclude='**/.git' \ + --exclude='**/.hg' \ + --exclude='**/.vs' \ + --exclude='**/.vscode' \ + --exclude='deployment' \ + --exclude='**/bin' \ + --exclude='**/obj' \ + --exclude='**/.nuget' \ + --exclude='*.deb' \ + --exclude='*.rpm' \ + -zcf \ + "$package_temporary_dir/jellyfin-${VERSION}/jellyfin.tar.gz" \ + -C "../.." \ + ./ + echo "Extracting filtered package." + tar -xzf "$package_temporary_dir/jellyfin-${VERSION}/jellyfin.tar.gz" -C "$package_temporary_dir/jellyfin-${VERSION}" + echo "Removing filtered package." + rm "$package_temporary_dir/jellyfin-${VERSION}/jellyfin.tar.gz" + echo "Repackaging package into final tarball." + tar -zcf "$pkg_src_dir/jellyfin-${VERSION}.tar.gz" -C "$package_temporary_dir" "jellyfin-${VERSION}" +fi + +docker build ../.. -t "$image_name" -f ./Dockerfile mkdir -p "$output_dir" -docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find / -maxdepth 1 -type f -name "jellyfin*" -exec mv {} /temp \;' +docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find /build/rpmbuild -maxdepth 3 -type f -name "jellyfin*.rpm" -exec mv {} /temp \;' chown -R "$current_user" "$package_temporary_dir" if [ $? -ne 0 ]; then # Some platforms need this to chown the file properly. (Platforms with native docker, not just the client) sudo chown -R "$current_user" "$package_temporary_dir" fi -mv "$package_temporary_dir"/* "$output_dir" +mv "$package_temporary_dir"/*.rpm "$output_dir" diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/fedora-package-x64/pkg-src/jellyfin.spec index b008ec8347..406dc399d2 100644 --- a/deployment/fedora-package-x64/pkg-src/jellyfin.spec +++ b/deployment/fedora-package-x64/pkg-src/jellyfin.spec @@ -1,24 +1,23 @@ %global debug_package %{nil} # jellyfin tag to package -%global gittag v10.0.2 +%global gittag v10.0.1 # Taglib-sharp commit of the submodule since github archive doesn't include submodules %global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 %global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) Name: jellyfin -Version: 10.0.2 +Version: 10.0.1 Release: 1%{?dist} -Summary: The Free Software Media Browser. +Summary: The Free Software Media Browser License: GPLv2 URL: https://jellyfin.media -Source0: https://github.com/%{name}/%{name}/archive/%{gittag}.tar.gz +Source0: %{name}-%{version}.tar.gz Source1: jellyfin.service Source2: jellyfin.env Source3: jellyfin.sudoers Source4: restart.sh -Source5: https://github.com/mono/taglib-sharp/archive/%{taglib_commit}/taglib-sharp-%{taglib_shortcommit}.tar.gz -Source6: jellyfin.override.conf -Source7: jellyfin-firewalld.xml +Source5: jellyfin.override.conf +Source6: jellyfin-firewalld.xml %{?systemd_requires} BuildRequires: systemd @@ -45,23 +44,15 @@ Jellyfin is a free software media system that puts you in control of managing an %prep %autosetup -n %{name}-%{version} -pushd ThirdParty - tar xf %{S:5} - rm -rf taglib-sharp - mv taglib-sharp-%{taglib_commit} taglib-sharp -popd %build -export DOTNET_CLI_TELEMETRY_OPTOUT=1 -export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -dotnet build --runtime fedora-x64 Jellyfin.Server %install export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime fedora-x64 Jellyfin.Server %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE -%{__install} -D -m 0644 %{SOURCE6} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__install} -D -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json %{__mkdir} -p %{buildroot}%{_bindir} tee %{buildroot}%{_bindir}/jellyfin << EOF @@ -76,10 +67,10 @@ EOF %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers %{__install} -D -m 0755 %{SOURCE4} %{buildroot}%{_libexecdir}/%{name}/restart.sh -%{__install} -D -m 0644 %{SOURCE7} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml +%{__install} -D -m 0644 %{SOURCE6} %{buildroot}%{_prefix}/lib/firewalld/service/%{name}.xml %files -%{_libdir}/%{name}/dashboard-ui/* +%{_libdir}/%{name}/jellyfin-web/* %attr(755,root,root) %{_bindir}/%{name} %{_libdir}/%{name}/*.json %{_libdir}/%{name}/*.pdb diff --git a/deployment/framework/build.sh b/deployment/framework/build.sh old mode 100644 new mode 100755 diff --git a/deployment/framework/clean.sh b/deployment/framework/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/framework/package.sh b/deployment/framework/package.sh old mode 100644 new mode 100755 diff --git a/deployment/linux-x64/build.sh b/deployment/linux-x64/build.sh old mode 100644 new mode 100755 diff --git a/deployment/linux-x64/clean.sh b/deployment/linux-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/linux-x64/package.sh b/deployment/linux-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/osx-x64/build.sh b/deployment/osx-x64/build.sh old mode 100644 new mode 100755 diff --git a/deployment/osx-x64/clean.sh b/deployment/osx-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/osx-x64/package.sh b/deployment/osx-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/ubuntu-x64/build.sh b/deployment/ubuntu-x64/build.sh old mode 100644 new mode 100755 diff --git a/deployment/ubuntu-x64/clean.sh b/deployment/ubuntu-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/ubuntu-x64/package.sh b/deployment/ubuntu-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x64/build.sh b/deployment/win-x64/build.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x64/clean.sh b/deployment/win-x64/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x64/package.sh b/deployment/win-x64/package.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x86/build.sh b/deployment/win-x86/build.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x86/clean.sh b/deployment/win-x86/clean.sh old mode 100644 new mode 100755 diff --git a/deployment/win-x86/package.sh b/deployment/win-x86/package.sh old mode 100644 new mode 100755 From 4b00b0cc8773a5a9aea06220230fe9affd2aed4d Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 03:04:36 +0100 Subject: [PATCH 26/45] Fixed fedora rpm build unexpected dependency on liblttng-ust. Fixed the docker builds and added manifest generation. --- deployment/common.build.sh | 8 ++++---- .../docker/{Dockerfile => Dockerfile.amd64} | 4 ++-- .../{Dockerfile.aarch64 => Dockerfile.arm32v7} | 6 +++--- deployment/docker/Dockerfile.arm64v8 | 17 +++++++++++++++++ deployment/docker/build.sh | 8 +++++++- deployment/docker/package.sh | 12 ++++++++++++ .../fedora-package-x64/pkg-src/jellyfin.spec | 1 + 7 files changed, 46 insertions(+), 10 deletions(-) rename deployment/docker/{Dockerfile => Dockerfile.amd64} (88%) rename deployment/docker/{Dockerfile.aarch64 => Dockerfile.arm32v7} (79%) create mode 100644 deployment/docker/Dockerfile.arm64v8 create mode 100755 deployment/docker/package.sh diff --git a/deployment/common.build.sh b/deployment/common.build.sh index 5996a4ec9d..a368928bab 100755 --- a/deployment/common.build.sh +++ b/deployment/common.build.sh @@ -46,13 +46,13 @@ build_jellyfin_docker() DOCKERFILE=${2-$DEFAULT_DOCKERFILE} IMAGE_TAG=${3-$DEFAULT_IMAGE_TAG} - echo -e "${CYAN}Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}'.${NC}" - docker build -t ${IMAGE_TAG} -f ${DOCKERFILE} ${ROOT} + echo -e "${CYAN}Building jellyfin docker image in '${BUILD_CONTEXT}' with Dockerfile '${DOCKERFILE}' and tag '${IMAGE_TAG}'.${NC}" + docker build -t ${IMAGE_TAG} -f ${DOCKERFILE} ${BUILD_CONTEXT} EXIT_CODE=$? if [ $EXIT_CODE -eq 0 ]; then - echo -e "${GREEN}[DONE] Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}' complete.${NC}" + echo -e "${GREEN}[DONE] Building jellyfin docker image in '${BUILD_CONTEXT}' with Dockerfile '${DOCKERFILE}' and tag '${IMAGE_TAG}' complete.${NC}" else - echo -e "${RED}[FAIL] Building jellyfin docker image in '${ROOT}' with Dockerfile ${CONFIG} and tag '${IMAGE_TAG}' FAILED.${NC}" + echo -e "${RED}[FAIL] Building jellyfin docker image in '${BUILD_CONTEXT}' with Dockerfile '${DOCKERFILE}' and tag '${IMAGE_TAG}' FAILED.${NC}" fi ) diff --git a/deployment/docker/Dockerfile b/deployment/docker/Dockerfile.amd64 similarity index 88% rename from deployment/docker/Dockerfile rename to deployment/docker/Dockerfile.amd64 index c32cdcf9b8..62f8e4fa40 100644 --- a/deployment/docker/Dockerfile +++ b/deployment/docker/Dockerfile.amd64 @@ -23,6 +23,6 @@ COPY --from=builder /jellyfin /jellyfin COPY --from=ffmpeg /ffmpeg-bin/* /usr/bin/ EXPOSE 8096 VOLUME /config /media -RUN apt update \ - && apt install -y libfontconfig1 --no-install-recommends # needed for Skia +RUN apt-get update \ + && apt-get install -y libfontconfig1 --no-install-recommends # needed for Skia ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config diff --git a/deployment/docker/Dockerfile.aarch64 b/deployment/docker/Dockerfile.arm32v7 similarity index 79% rename from deployment/docker/Dockerfile.aarch64 rename to deployment/docker/Dockerfile.arm32v7 index d1423dda2b..072b9cdebd 100644 --- a/deployment/docker/Dockerfile.aarch64 +++ b/deployment/docker/Dockerfile.arm32v7 @@ -8,10 +8,10 @@ RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ && dotnet clean \ && dotnet publish --configuration release --output /jellyfin Jellyfin.Server -FROM microsoft/dotnet:${DOTNET_VERSION}-runtime +FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm32v7 COPY --from=builder /jellyfin /jellyfin EXPOSE 8096 -RUN apt update \ - && apt install -y ffmpeg +RUN apt-get update \ + && apt-get install -y ffmpeg VOLUME /config /media ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config diff --git a/deployment/docker/Dockerfile.arm64v8 b/deployment/docker/Dockerfile.arm64v8 new file mode 100644 index 0000000000..fecb8cbfbb --- /dev/null +++ b/deployment/docker/Dockerfile.arm64v8 @@ -0,0 +1,17 @@ +ARG DOTNET_VERSION=3.0 + +FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder +WORKDIR /repo +COPY . . +RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ + && find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \ + && dotnet clean \ + && dotnet publish --configuration release --output /jellyfin Jellyfin.Server + +FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm64v8 +COPY --from=builder /jellyfin /jellyfin +EXPOSE 8096 +RUN apt-get update \ + && apt-get install -y ffmpeg +VOLUME /config /media +ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh index b75cedc013..40cf90d288 100755 --- a/deployment/docker/build.sh +++ b/deployment/docker/build.sh @@ -4,4 +4,10 @@ source ../common.build.sh VERSION=`get_version ../..` -build_jellyfin_docker ../.. Dockerfile jellyfin:${VERSION} \ No newline at end of file +build_jellyfin_docker ../.. Dockerfile.amd64 jellyfin:amd64-${VERSION} + +build_jellyfin_docker ../.. Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 + +build_jellyfin_docker ../.. Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} arm32v7 + + diff --git a/deployment/docker/package.sh b/deployment/docker/package.sh new file mode 100755 index 0000000000..402ac13552 --- /dev/null +++ b/deployment/docker/package.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +source ../common.build.sh + +VERSION=`get_version ../..` + +docker manifest create jellyfin:${VERSION} jellyfin:amd64-${VERSION} jellyfin:arm32v7-${VERSION} jellyfin:arm64v8-${VERSION} +docker manifest annotate jellyfin:amd64-${VERSION} --os linux --arch amd64 +docker manifest annotate jellyfin:arm32v7-${VERSION} --os linux --arch arm --variant armv7 +docker manifest annotate jellyfin:arm64v8-${VERSION} --os linux --arch arm64 --variant armv8 + +#TODO publish.sh - docker manifest push jellyfin:${VERSION} \ No newline at end of file diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/fedora-package-x64/pkg-src/jellyfin.spec index 406dc399d2..acab6b13bd 100644 --- a/deployment/fedora-package-x64/pkg-src/jellyfin.spec +++ b/deployment/fedora-package-x64/pkg-src/jellyfin.spec @@ -5,6 +5,7 @@ %global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 %global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) +AutoReq: no Name: jellyfin Version: 10.0.1 Release: 1%{?dist} From 2c62f8dbd519dbb33cfb382297f0d6fef2138f69 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 03:07:16 +0100 Subject: [PATCH 27/45] Renamed main script to be more correct for what it does. --- deployment/{build.sh => make.sh} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename deployment/{build.sh => make.sh} (67%) diff --git a/deployment/build.sh b/deployment/make.sh similarity index 67% rename from deployment/build.sh rename to deployment/make.sh index 5628d3ad52..ac7d03bab7 100755 --- a/deployment/build.sh +++ b/deployment/make.sh @@ -7,7 +7,9 @@ pushd ../Jellyfin.Versioning #./update-version popd -# Execute all build.sh and package.sh and sign.sh scripts in every folder. In that order. Script should check for artifacts themselves. +#TODO enabled proper flag parsing for enabling and disabling building, signing, packaging and publishing + +# Execute all build.sh, package.sh, sign.sh and publish.sh scripts in every folder. In that order. Script should check for artifacts themselves. echo "Running for platforms '$@'." for directory in */ ; do platform=`basename "${directory}"` @@ -23,6 +25,9 @@ for directory in */ ; do if [ -f sign.sh ]; then ./sign.sh fi + if [ -f publish.sh ]; then + ./publish.sh + fi popd else echo "Skipping $platform." From 2c65fe53f264f120b5ed028cc81df629e0e6a3bc Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 03:09:38 +0100 Subject: [PATCH 28/45] Enabled update-version in anticipation of the versioning PR. --- deployment/make.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deployment/make.sh b/deployment/make.sh index ac7d03bab7..6b8d8de083 100755 --- a/deployment/make.sh +++ b/deployment/make.sh @@ -3,8 +3,7 @@ git submodule update --init --recursive pushd ../Jellyfin.Versioning -#TODO Uncomment the next line with PR is merged. -#./update-version +./update-version popd #TODO enabled proper flag parsing for enabling and disabling building, signing, packaging and publishing From ba671569b4a5f897c10b209d9e33fafca0e8621f Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 15:54:52 +0100 Subject: [PATCH 29/45] Moved main docker file. --- deployment/docker/Dockerfile.amd64 => Dockerfile | 0 deployment/docker/build.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename deployment/docker/Dockerfile.amd64 => Dockerfile (100%) diff --git a/deployment/docker/Dockerfile.amd64 b/Dockerfile similarity index 100% rename from deployment/docker/Dockerfile.amd64 rename to Dockerfile diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh index 40cf90d288..783ebe1e30 100755 --- a/deployment/docker/build.sh +++ b/deployment/docker/build.sh @@ -4,7 +4,7 @@ source ../common.build.sh VERSION=`get_version ../..` -build_jellyfin_docker ../.. Dockerfile.amd64 jellyfin:amd64-${VERSION} +build_jellyfin_docker ../.. ../../Dockerfile jellyfin:amd64-${VERSION} build_jellyfin_docker ../.. Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 From b73d081bd28e2465710d2b5f5934b444def73e5a Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 15:56:06 +0100 Subject: [PATCH 30/45] Updated docker build script. --- deployment/docker/build.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh index 783ebe1e30..d598544156 100755 --- a/deployment/docker/build.sh +++ b/deployment/docker/build.sh @@ -9,5 +9,3 @@ build_jellyfin_docker ../.. ../../Dockerfile jellyfin:amd64-${VERSION} build_jellyfin_docker ../.. Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 build_jellyfin_docker ../.. Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} arm32v7 - - From 672013c23d10d79b4d87b509ebf7b50c29870af7 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sat, 12 Jan 2019 16:34:13 +0100 Subject: [PATCH 31/45] Add TODO for netcore version upgrade. --- deployment/docker/Dockerfile.arm32v7 | 1 + deployment/docker/Dockerfile.arm64v8 | 1 + 2 files changed, 2 insertions(+) diff --git a/deployment/docker/Dockerfile.arm32v7 b/deployment/docker/Dockerfile.arm32v7 index 072b9cdebd..816b662aae 100644 --- a/deployment/docker/Dockerfile.arm32v7 +++ b/deployment/docker/Dockerfile.arm32v7 @@ -3,6 +3,7 @@ ARG DOTNET_VERSION=3.0 FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder WORKDIR /repo COPY . . +#TODO Remove or update the sed line when we update dotnet version. RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ && find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \ && dotnet clean \ diff --git a/deployment/docker/Dockerfile.arm64v8 b/deployment/docker/Dockerfile.arm64v8 index fecb8cbfbb..932b503913 100644 --- a/deployment/docker/Dockerfile.arm64v8 +++ b/deployment/docker/Dockerfile.arm64v8 @@ -3,6 +3,7 @@ ARG DOTNET_VERSION=3.0 FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder WORKDIR /repo COPY . . +#TODO Remove or update the sed line when we update dotnet version. RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ && find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \ && dotnet clean \ From d7b7be395b76c7fcc49d3baffeb59d51a9b36378 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sun, 13 Jan 2019 23:24:43 +0100 Subject: [PATCH 32/45] Moved ARM dockerfiles back to root. --- deployment/docker/Dockerfile.arm32v7 => Dockerfile.arm32v7 | 0 deployment/docker/Dockerfile.arm64v8 => Dockerfile.arm64v8 | 0 deployment/docker/build.sh | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename deployment/docker/Dockerfile.arm32v7 => Dockerfile.arm32v7 (100%) rename deployment/docker/Dockerfile.arm64v8 => Dockerfile.arm64v8 (100%) diff --git a/deployment/docker/Dockerfile.arm32v7 b/Dockerfile.arm32v7 similarity index 100% rename from deployment/docker/Dockerfile.arm32v7 rename to Dockerfile.arm32v7 diff --git a/deployment/docker/Dockerfile.arm64v8 b/Dockerfile.arm64v8 similarity index 100% rename from deployment/docker/Dockerfile.arm64v8 rename to Dockerfile.arm64v8 diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh index d598544156..0f617ad094 100755 --- a/deployment/docker/build.sh +++ b/deployment/docker/build.sh @@ -6,6 +6,6 @@ VERSION=`get_version ../..` build_jellyfin_docker ../.. ../../Dockerfile jellyfin:amd64-${VERSION} -build_jellyfin_docker ../.. Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 +build_jellyfin_docker ../.. ../../Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 -build_jellyfin_docker ../.. Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} arm32v7 +build_jellyfin_docker ../.. ../../Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} arm32v7 From ca320ba7acbd1018eba7816fac9271172e91ed1d Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sun, 13 Jan 2019 23:34:40 +0100 Subject: [PATCH 33/45] Sudo fix for debian and fedora. --- deployment/debian-package-x64/package.sh | 8 +++----- deployment/fedora-package-x64/package.sh | 7 ++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/deployment/debian-package-x64/package.sh b/deployment/debian-package-x64/package.sh index 7909b0a84e..dec953961f 100755 --- a/deployment/debian-package-x64/package.sh +++ b/deployment/debian-package-x64/package.sh @@ -25,9 +25,7 @@ docker build ../.. -t "$image_name" -f ./Dockerfile --build-arg SOURCEDIR="/jell mkdir -p "$package_temporary_dir" mkdir -p "$output_dir" docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find / -maxdepth 1 -type f -name "jellyfin*" -exec mv {} /temp \;' -chown -R "$current_user" "$package_temporary_dir" -if [ $? -ne 0 ]; then - # Some platforms need this to chown the file properly. (Platforms with native docker, not just the client) - sudo chown -R "$current_user" "$package_temporary_dir" -fi +chown -R "$current_user" "$package_temporary_dir" \ +|| sudo chown -R "$current_user" "$package_temporary_dir" + mv "$package_temporary_dir"/* "$output_dir" diff --git a/deployment/fedora-package-x64/package.sh b/deployment/fedora-package-x64/package.sh index 56a120844f..416c8213b9 100755 --- a/deployment/fedora-package-x64/package.sh +++ b/deployment/fedora-package-x64/package.sh @@ -78,9 +78,6 @@ fi docker build ../.. -t "$image_name" -f ./Dockerfile mkdir -p "$output_dir" docker run --rm -v "$package_temporary_dir:/temp" "$image_name" sh -c 'find /build/rpmbuild -maxdepth 3 -type f -name "jellyfin*.rpm" -exec mv {} /temp \;' -chown -R "$current_user" "$package_temporary_dir" -if [ $? -ne 0 ]; then - # Some platforms need this to chown the file properly. (Platforms with native docker, not just the client) - sudo chown -R "$current_user" "$package_temporary_dir" -fi +chown -R "$current_user" "$package_temporary_dir" \ +|| sudo chown -R "$current_user" "$package_temporary_dir" mv "$package_temporary_dir"/*.rpm "$output_dir" From 9b224d7080d0dce986937229e9ff0c8923f7ce95 Mon Sep 17 00:00:00 2001 From: Erwin de Haan Date: Sun, 13 Jan 2019 23:43:12 +0100 Subject: [PATCH 34/45] Merged the two ARM platforms. To be split apart when a binary ffmpeg is required. --- Dockerfile.arm32v7 => Dockerfile.arm | 2 +- Dockerfile.arm64v8 | 18 ------------------ deployment/docker/build.sh | 5 +++-- deployment/docker/package.sh | 6 +++--- 4 files changed, 7 insertions(+), 24 deletions(-) rename Dockerfile.arm32v7 => Dockerfile.arm (89%) delete mode 100644 Dockerfile.arm64v8 diff --git a/Dockerfile.arm32v7 b/Dockerfile.arm similarity index 89% rename from Dockerfile.arm32v7 rename to Dockerfile.arm index fd9dc6c15a..a0b3d0e1da 100644 --- a/Dockerfile.arm32v7 +++ b/Dockerfile.arm @@ -12,7 +12,7 @@ RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ --output /jellyfin \ Jellyfin.Server -FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm32v7 +FROM microsoft/dotnet:${DOTNET_VERSION}-runtime COPY --from=builder /jellyfin /jellyfin EXPOSE 8096 RUN apt-get update \ diff --git a/Dockerfile.arm64v8 b/Dockerfile.arm64v8 deleted file mode 100644 index 932b503913..0000000000 --- a/Dockerfile.arm64v8 +++ /dev/null @@ -1,18 +0,0 @@ -ARG DOTNET_VERSION=3.0 - -FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder -WORKDIR /repo -COPY . . -#TODO Remove or update the sed line when we update dotnet version. -RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \ - && find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \ - && dotnet clean \ - && dotnet publish --configuration release --output /jellyfin Jellyfin.Server - -FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm64v8 -COPY --from=builder /jellyfin /jellyfin -EXPOSE 8096 -RUN apt-get update \ - && apt-get install -y ffmpeg -VOLUME /config /media -ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh index 0f617ad094..444208c85c 100755 --- a/deployment/docker/build.sh +++ b/deployment/docker/build.sh @@ -6,6 +6,7 @@ VERSION=`get_version ../..` build_jellyfin_docker ../.. ../../Dockerfile jellyfin:amd64-${VERSION} -build_jellyfin_docker ../.. ../../Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} arm64v8 +build_jellyfin_docker ../.. ../../Dockerfile.arm jellyfin:arm-${VERSION} -build_jellyfin_docker ../.. ../../Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} arm32v7 +#build_jellyfin_docker ../.. ../../Dockerfile.arm64v8 jellyfin:arm64v8-${VERSION} +#build_jellyfin_docker ../.. ../../Dockerfile.arm32v7 jellyfin:arm32v7-${VERSION} diff --git a/deployment/docker/package.sh b/deployment/docker/package.sh index 402ac13552..d74426e2fe 100755 --- a/deployment/docker/package.sh +++ b/deployment/docker/package.sh @@ -6,7 +6,7 @@ VERSION=`get_version ../..` docker manifest create jellyfin:${VERSION} jellyfin:amd64-${VERSION} jellyfin:arm32v7-${VERSION} jellyfin:arm64v8-${VERSION} docker manifest annotate jellyfin:amd64-${VERSION} --os linux --arch amd64 -docker manifest annotate jellyfin:arm32v7-${VERSION} --os linux --arch arm --variant armv7 -docker manifest annotate jellyfin:arm64v8-${VERSION} --os linux --arch arm64 --variant armv8 +#docker manifest annotate jellyfin:arm32v7-${VERSION} --os linux --arch arm --variant armv7 +#docker manifest annotate jellyfin:arm64v8-${VERSION} --os linux --arch arm64 --variant armv8 -#TODO publish.sh - docker manifest push jellyfin:${VERSION} \ No newline at end of file +#TODO publish.sh - docker manifest push jellyfin:${VERSION} From eca3c099d9bd54f1e745143589c12fb9008aee13 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Fri, 4 Jan 2019 22:42:56 +0100 Subject: [PATCH 35/45] removed a bunch of validation, security, registration, premiere, whatever bs --- .../ApplicationHost.cs | 13 +- .../HttpServer/HttpListenerHost.cs | 2 - .../LiveTv/EmbyTV/EmbyTV.cs | 127 +++++------ .../LiveTv/LiveTvManager.cs | 53 ++--- .../Security/PluginSecurityManager.cs | 212 ------------------ .../Updates/InstallationManager.cs | 51 ++--- MediaBrowser.Api/PluginService.cs | 199 ++++------------ MediaBrowser.Api/System/SystemService.cs | 6 +- .../Security/IRequiresRegistration.cs | 15 -- .../Security/ISecurityManager.cs | 32 --- .../Security/PaymentRequiredException.cs | 8 - .../Updates/IInstallationManager.cs | 4 +- .../Entities/MBRegistrationRecord.cs | 14 -- .../Entities/PluginSecurityInfo.cs | 21 -- 14 files changed, 132 insertions(+), 625 deletions(-) delete mode 100644 Emby.Server.Implementations/Security/PluginSecurityManager.cs delete mode 100644 MediaBrowser.Common/Security/IRequiresRegistration.cs delete mode 100644 MediaBrowser.Common/Security/ISecurityManager.cs delete mode 100644 MediaBrowser.Common/Security/PaymentRequiredException.cs delete mode 100644 MediaBrowser.Model/Entities/MBRegistrationRecord.cs delete mode 100644 MediaBrowser.Model/Entities/PluginSecurityInfo.cs diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 386f429598..e975575884 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -41,7 +41,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Model.Extensions; -using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Channels; @@ -340,11 +339,6 @@ namespace Emby.Server.Implementations /// /// The installation manager. protected IInstallationManager InstallationManager { get; private set; } - /// - /// Gets the security manager. - /// - /// The security manager. - protected ISecurityManager SecurityManager { get; private set; } /// /// Gets or sets the zip client. @@ -804,10 +798,7 @@ namespace Emby.Server.Implementations SocketFactory = new SocketFactory(LoggerFactory.CreateLogger("SocketFactory")); RegisterSingleInstance(SocketFactory); - SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LoggerFactory, FileSystemManager, CryptographyProvider); - RegisterSingleInstance(SecurityManager); - - InstallationManager = new InstallationManager(LoggerFactory.CreateLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime); + InstallationManager = new InstallationManager(LoggerFactory.CreateLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime); RegisterSingleInstance(InstallationManager); ZipClient = new ZipClient(FileSystemManager); @@ -922,7 +913,7 @@ namespace Emby.Server.Implementations PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LoggerFactory.CreateLogger("PlaylistManager"), UserManager, ProviderManager); RegisterSingleInstance(PlaylistManager); - LiveTvManager = new LiveTvManager(this, HttpClient, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager, SecurityManager, () => ChannelManager); + LiveTvManager = new LiveTvManager(this, HttpClient, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager, () => ChannelManager); RegisterSingleInstance(LiveTvManager); UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index d51563d513..8219b85a2e 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -13,7 +13,6 @@ using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Services; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Security; using MediaBrowser.Controller; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Serialization; @@ -85,7 +84,6 @@ namespace Emby.Server.Implementations.HttpServer {typeof (FileNotFoundException), 404}, //{typeof (DirectoryNotFoundException), 404}, {typeof (SecurityException), 401}, - {typeof (PaymentRequiredException), 402}, {typeof (ArgumentException), 400} }; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 75ac625ef1..2c671f5105 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1183,14 +1183,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return; } - var registration = await _liveTvManager.GetRegistrationInfo("dvr").ConfigureAwait(false); - if (!registration.IsValid) - { - _logger.LogWarning("Emby Premiere required to use Emby DVR."); - OnTimerOutOfDate(timer); - return; - } - var activeRecordingInfo = new ActiveRecordingInfo { CancellationTokenSource = new CancellationTokenSource(), @@ -2379,79 +2371,74 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var allTimers = GetTimersForSeries(seriesTimer) .ToList(); - var registration = await _liveTvManager.GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); var enabledTimersForSeries = new List(); - - if (registration.IsValid) + foreach (var timer in allTimers) { - foreach (var timer in allTimers) + var existingTimer = _timerProvider.GetTimer(timer.Id); + + if (existingTimer == null) { - var existingTimer = _timerProvider.GetTimer(timer.Id); + existingTimer = string.IsNullOrWhiteSpace(timer.ProgramId) + ? null + : _timerProvider.GetTimerByProgramId(timer.ProgramId); + } - if (existingTimer == null) + if (existingTimer == null) + { + if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) { - existingTimer = string.IsNullOrWhiteSpace(timer.ProgramId) - ? null - : _timerProvider.GetTimerByProgramId(timer.ProgramId); - } - - if (existingTimer == null) - { - if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) - { - timer.Status = RecordingStatus.Cancelled; - } - else - { - enabledTimersForSeries.Add(timer); - } - _timerProvider.Add(timer); - - if (TimerCreated != null) - { - TimerCreated(this, new GenericEventArgs(timer)); - } + timer.Status = RecordingStatus.Cancelled; } else { - // Only update if not currently active - test both new timer and existing in case Id's are different - // Id's could be different if the timer was created manually prior to series timer creation - ActiveRecordingInfo activeRecordingInfo; - if (!_activeRecordings.TryGetValue(timer.Id, out activeRecordingInfo) && !_activeRecordings.TryGetValue(existingTimer.Id, out activeRecordingInfo)) + enabledTimersForSeries.Add(timer); + } + _timerProvider.Add(timer); + + if (TimerCreated != null) + { + TimerCreated(this, new GenericEventArgs(timer)); + } + } + else + { + // Only update if not currently active - test both new timer and existing in case Id's are different + // Id's could be different if the timer was created manually prior to series timer creation + ActiveRecordingInfo activeRecordingInfo; + if (!_activeRecordings.TryGetValue(timer.Id, out activeRecordingInfo) && !_activeRecordings.TryGetValue(existingTimer.Id, out activeRecordingInfo)) + { + UpdateExistingTimerWithNewMetadata(existingTimer, timer); + + // Needed by ShouldCancelTimerForSeriesTimer + timer.IsManual = existingTimer.IsManual; + + if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) { - UpdateExistingTimerWithNewMetadata(existingTimer, timer); - - // Needed by ShouldCancelTimerForSeriesTimer - timer.IsManual = existingTimer.IsManual; - - if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) - { - existingTimer.Status = RecordingStatus.Cancelled; - } - else if (!existingTimer.IsManual) - { - existingTimer.Status = RecordingStatus.New; - } - - if (existingTimer.Status != RecordingStatus.Cancelled) - { - enabledTimersForSeries.Add(existingTimer); - } - - if (updateTimerSettings) - { - existingTimer.KeepUntil = seriesTimer.KeepUntil; - existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired; - existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired; - existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds; - existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds; - existingTimer.Priority = seriesTimer.Priority; - } - - existingTimer.SeriesTimerId = seriesTimer.Id; - _timerProvider.Update(existingTimer); + existingTimer.Status = RecordingStatus.Cancelled; } + else if (!existingTimer.IsManual) + { + existingTimer.Status = RecordingStatus.New; + } + + if (existingTimer.Status != RecordingStatus.Cancelled) + { + enabledTimersForSeries.Add(existingTimer); + } + + if (updateTimerSettings) + { + existingTimer.KeepUntil = seriesTimer.KeepUntil; + existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired; + existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired; + existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds; + existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds; + existingTimer.Priority = seriesTimer.Priority; + } + + existingTimer.SeriesTimerId = seriesTimer.Id; + _timerProvider.Update(existingTimer); } } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 4e38ad7be0..c360a6a82d 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -22,7 +22,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; -using MediaBrowser.Common.Security; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Events; @@ -51,7 +50,6 @@ namespace Emby.Server.Implementations.LiveTv private readonly ITaskManager _taskManager; private readonly IJsonSerializer _jsonSerializer; private readonly IProviderManager _providerManager; - private readonly ISecurityManager _security; private readonly Func _channelManager; private readonly IDtoService _dtoService; @@ -78,7 +76,23 @@ namespace Emby.Server.Implementations.LiveTv private IServerApplicationHost _appHost; private IHttpClient _httpClient; - public LiveTvManager(IServerApplicationHost appHost, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager, IFileSystem fileSystem, ISecurityManager security, Func channelManager) + public LiveTvManager( + IServerApplicationHost appHost, + IHttpClient httpClient, + IServerConfigurationManager config, + ILogger logger, + IItemRepository itemRepo, + IImageProcessor imageProcessor, + IUserDataManager userDataManager, + IDtoService dtoService, + IUserManager userManager, + ILibraryManager libraryManager, + ITaskManager taskManager, + ILocalizationManager localization, + IJsonSerializer jsonSerializer, + IProviderManager providerManager, + IFileSystem fileSystem, + Func channelManager) { _appHost = appHost; _config = config; @@ -91,7 +105,6 @@ namespace Emby.Server.Implementations.LiveTv _jsonSerializer = jsonSerializer; _providerManager = providerManager; _fileSystem = fileSystem; - _security = security; _dtoService = dtoService; _userDataManager = userDataManager; _channelManager = channelManager; @@ -2087,14 +2100,6 @@ namespace Emby.Server.Implementations.LiveTv public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) { - var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); - - if (!registration.IsValid) - { - _logger.LogInformation("Creating series recordings requires an active Emby Premiere subscription."); - return; - } - var service = GetService(timer.ServiceName); var info = await _tvDtoService.GetSeriesTimerInfo(timer, true, this, cancellationToken).ConfigureAwait(false); @@ -2436,30 +2441,6 @@ namespace Emby.Server.Implementations.LiveTv } } - public Task GetRegistrationInfo(string feature) - { - if (string.Equals(feature, "seriesrecordings", StringComparison.OrdinalIgnoreCase)) - { - feature = "embytvseriesrecordings"; - } - - if (string.Equals(feature, "dvr-l", StringComparison.OrdinalIgnoreCase)) - { - var config = GetConfiguration(); - if (config.TunerHosts.Length > 0 && - config.ListingProviders.Count(i => (i.EnableAllTuners || i.EnabledTuners.Length > 0) && string.Equals(i.Type, SchedulesDirect.TypeName, StringComparison.OrdinalIgnoreCase)) > 0) - { - return Task.FromResult(new MBRegistrationRecord - { - IsRegistered = true, - IsValid = true - }); - } - } - - return _security.GetRegistrationStatus(feature); - } - public Task> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken) { var info = GetConfiguration().ListingProviders.First(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)); diff --git a/Emby.Server.Implementations/Security/PluginSecurityManager.cs b/Emby.Server.Implementations/Security/PluginSecurityManager.cs deleted file mode 100644 index dc606f2b98..0000000000 --- a/Emby.Server.Implementations/Security/PluginSecurityManager.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Security; -using MediaBrowser.Controller; -using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; -using Microsoft.Extensions.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Serialization; - -namespace Emby.Server.Implementations.Security -{ - /// - /// Class PluginSecurityManager - /// - public class PluginSecurityManager : ISecurityManager - { - private const string MBValidateUrl = "https://mb3admin.local/admin/service/registration/validate"; - private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "https://mb3admin.local/admin/service/appstore/register"; - - public async Task IsSupporter() - { - var result = await GetRegistrationStatusInternal("MBSupporter", false, _appHost.ApplicationVersion.ToString(), CancellationToken.None).ConfigureAwait(false); - - return result.IsRegistered; - } - - private MBLicenseFile _licenseFile; - private MBLicenseFile LicenseFile => _licenseFile ?? (_licenseFile = new MBLicenseFile(_appPaths, _fileSystem, _cryptographyProvider)); - - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _jsonSerializer; - private readonly IServerApplicationHost _appHost; - private readonly ILogger _logger; - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - private readonly ICryptoProvider _cryptographyProvider; - - /// - /// Initializes a new instance of the class. - /// - public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, - IApplicationPaths appPaths, ILoggerFactory loggerFactory, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) - { - if (httpClient == null) - { - throw new ArgumentNullException(nameof(httpClient)); - } - - _appHost = appHost; - _httpClient = httpClient; - _jsonSerializer = jsonSerializer; - _appPaths = appPaths; - _fileSystem = fileSystem; - _cryptographyProvider = cryptographyProvider; - _logger = loggerFactory.CreateLogger("SecurityManager"); - } - - /// - /// Gets the registration status. - /// This overload supports existing plug-ins. - /// - public Task GetRegistrationStatus(string feature) - { - return GetRegistrationStatusInternal(feature, false, null, CancellationToken.None); - } - - /// - /// Gets or sets the supporter key. - /// - /// The supporter key. - public string SupporterKey - { - get => LicenseFile.RegKey; - set => throw new Exception("Please call UpdateSupporterKey"); - } - - public async Task UpdateSupporterKey(string newValue) - { - if (newValue != null) - { - newValue = newValue.Trim(); - } - - if (!string.Equals(newValue, LicenseFile.RegKey, StringComparison.Ordinal)) - { - LicenseFile.RegKey = newValue; - LicenseFile.Save(); - - // Reset this - await GetRegistrationStatusInternal("MBSupporter", true, _appHost.ApplicationVersion.ToString(), CancellationToken.None).ConfigureAwait(false); - } - } - - /// - /// Register an app store sale with our back-end. It will validate the transaction with the store - /// and then register the proper feature and then fill in the supporter key on success. - /// - /// Json parameters to send to admin server - public async Task RegisterAppStoreSale(string parameters) - { - var options = new HttpRequestOptions() - { - Url = AppstoreRegUrl, - CancellationToken = CancellationToken.None, - BufferContent = false - }; - options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId); - options.RequestContent = parameters; - options.RequestContentType = "application/json"; - - try - { - using (var response = await _httpClient.Post(options).ConfigureAwait(false)) - { - var reg = await _jsonSerializer.DeserializeFromStreamAsync(response.Content).ConfigureAwait(false); - - if (reg == null) - { - var msg = "Result from appstore registration was null."; - _logger.LogError(msg); - throw new ArgumentException(msg); - } - if (!string.IsNullOrEmpty(reg.key)) - { - await UpdateSupporterKey(reg.key).ConfigureAwait(false); - } - } - - } - catch (ArgumentException) - { - SaveAppStoreInfo(parameters); - throw; - } - catch (HttpException ex) - { - _logger.LogError(ex, "Error registering appstore purchase {parameters}", parameters ?? "NO PARMS SENT"); - - throw new Exception("Error registering store sale"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error registering appstore purchase {parameters}", parameters ?? "NO PARMS SENT"); - SaveAppStoreInfo(parameters); - //TODO - could create a re-try routine on start-up if this file is there. For now we can handle manually. - throw new Exception("Error registering store sale"); - } - - } - - private void SaveAppStoreInfo(string info) - { - // Save all transaction information to a file - - try - { - _fileSystem.WriteAllText(Path.Combine(_appPaths.ProgramDataPath, "apptrans-error.txt"), info); - } - catch (IOException) - { - - } - } - - private SemaphoreSlim _regCheckLock = new SemaphoreSlim(1, 1); - - private async Task GetRegistrationStatusInternal(string feature, bool forceCallToServer, string version, CancellationToken cancellationToken) - { - await _regCheckLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - var record = new MBRegistrationRecord - { - IsRegistered = true, - RegChecked = true, - TrialVersion = false, - IsValid = true, - RegError = false - }; - - return record; - } - finally - { - _regCheckLock.Release(); - } - } - - private bool IsInTrial(DateTime expirationDate, bool regChecked, bool isRegistered) - { - //don't set this until we've successfully obtained exp date - if (!regChecked) - { - return false; - } - - var isInTrial = expirationDate > DateTime.UtcNow; - - return isInTrial && !isRegistered; - } - } -} diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 0d5d723b76..27ec476cc1 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Progress; -using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Events; @@ -107,7 +106,6 @@ namespace Emby.Server.Implementations.Updates private readonly IApplicationPaths _appPaths; private readonly IHttpClient _httpClient; private readonly IJsonSerializer _jsonSerializer; - private readonly ISecurityManager _securityManager; private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; @@ -122,7 +120,16 @@ namespace Emby.Server.Implementations.Updates // netframework or netcore private readonly string _packageRuntime; - public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IServerConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string packageRuntime) + public InstallationManager( + ILogger logger, + IApplicationHost appHost, + IApplicationPaths appPaths, + IHttpClient httpClient, + IJsonSerializer jsonSerializer, + IServerConfigurationManager config, + IFileSystem fileSystem, + ICryptoProvider cryptographyProvider, + string packageRuntime) { if (logger == null) { @@ -136,7 +143,6 @@ namespace Emby.Server.Implementations.Updates _appPaths = appPaths; _httpClient = httpClient; _jsonSerializer = jsonSerializer; - _securityManager = securityManager; _config = config; _fileSystem = fileSystem; _cryptographyProvider = cryptographyProvider; @@ -163,41 +169,10 @@ namespace Emby.Server.Implementations.Updates string packageType = null, Version applicationVersion = null) { - if (withRegistration) - { - var data = new Dictionary - { - { "key", _securityManager.SupporterKey }, - { "mac", _applicationHost.SystemId }, - { "systemid", _applicationHost.SystemId } - }; + // TODO cvium + // var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - var options = new HttpRequestOptions - { - Url = "https://www.mb3admin.local/admin/service/package/retrieveall?includeAllRuntimes=true", - CancellationToken = cancellationToken - }; - - options.SetPostData(data); - - using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) - { - using (var json = response.Content) - { - cancellationToken.ThrowIfCancellationRequested(); - - var packages = await _jsonSerializer.DeserializeFromStreamAsync(json).ConfigureAwait(false); - - return FilterPackages(packages, packageType, applicationVersion); - } - } - } - else - { - var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - - return FilterPackages(packages, packageType, applicationVersion); - } + return new List(); //FilterPackages(packages, packageType, applicationVersion); } /// diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index c5a94e77c3..75defa998b 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -1,16 +1,13 @@ using MediaBrowser.Common; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; using System; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Services; using MediaBrowser.Common.Plugins; @@ -79,55 +76,6 @@ namespace MediaBrowser.Api public Stream RequestStream { get; set; } } - /// - /// Class GetPluginSecurityInfo - /// - [Route("/Plugins/SecurityInfo", "GET", Summary = "Gets plugin registration information", IsHidden = true)] - [Authenticated] - public class GetPluginSecurityInfo : IReturn - { - } - - /// - /// Class UpdatePluginSecurityInfo - /// - [Route("/Plugins/SecurityInfo", "POST", Summary = "Updates plugin registration information", IsHidden = true)] - [Authenticated(Roles = "Admin")] - public class UpdatePluginSecurityInfo : PluginSecurityInfo, IReturnVoid - { - } - - [Route("/Plugins/RegistrationRecords/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] - [Authenticated] - public class GetRegistrationStatus - { - [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string Name { get; set; } - } - - [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] - [Authenticated] - public class GetRegistration : IReturn - { - [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string Name { get; set; } - } - - public class RegistrationInfo - { - public string Name { get; set; } - public DateTime ExpirationDate { get; set; } - public bool IsTrial { get; set; } - public bool IsRegistered { get; set; } - } - - [Route("/Appstore/Register", "POST", Summary = "Registers an appstore sale", IsHidden = true)] - [Authenticated] - public class RegisterAppstoreSale - { - [ApiMember(Name = "Parameters", Description = "Java representation of parameters to pass through to admin server", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string Parameters { get; set; } - } /// /// Class PluginsService @@ -143,14 +91,11 @@ namespace MediaBrowser.Api /// The _app host /// private readonly IApplicationHost _appHost; - - private readonly ISecurityManager _securityManager; - private readonly IInstallationManager _installationManager; private readonly INetworkManager _network; private readonly IDeviceManager _deviceManager; - public PluginService(IJsonSerializer jsonSerializer, IApplicationHost appHost, ISecurityManager securityManager, IInstallationManager installationManager, INetworkManager network, IDeviceManager deviceManager) + public PluginService(IJsonSerializer jsonSerializer, IApplicationHost appHost, IInstallationManager installationManager, INetworkManager network, IDeviceManager deviceManager) : base() { if (jsonSerializer == null) @@ -159,39 +104,12 @@ namespace MediaBrowser.Api } _appHost = appHost; - _securityManager = securityManager; _installationManager = installationManager; _network = network; _deviceManager = deviceManager; _jsonSerializer = jsonSerializer; } - /// - /// Gets the specified request. - /// - /// The request. - /// System.Object. - public async Task Get(GetRegistrationStatus request) - { - var result = await _securityManager.GetRegistrationStatus(request.Name).ConfigureAwait(false); - - return ToOptimizedResult(result); - } - - public async Task Get(GetRegistration request) - { - var result = await _securityManager.GetRegistrationStatus(request.Name).ConfigureAwait(false); - - var info = new RegistrationInfo - { - ExpirationDate = result.ExpirationDate, - IsRegistered = result.IsRegistered, - IsTrial = result.TrialVersion, - Name = request.Name - }; - - return ToOptimizedResult(info); - } /// /// Gets the specified request. @@ -200,46 +118,46 @@ namespace MediaBrowser.Api /// System.Object. public async Task Get(GetPlugins request) { - var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); - var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value; - - // Don't fail just on account of image url's - try - { - var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None)); - - foreach (var plugin in result) - { - var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && string.Equals(i.guid.Replace("-", string.Empty), plugin.Id.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase)); - - if (pkg != null) - { - plugin.ImageUrl = pkg.thumbImage; - } - } - - if (requireAppStoreEnabled) - { - result = result - .Where(plugin => - { - var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && new Guid(plugin.Id).Equals(new Guid(i.guid))); - return pkg != null && pkg.enableInAppStore; - - }) - .ToArray(); - } - } - catch (Exception ex) - { - Logger.LogError(ex, "Error getting plugin list"); - // Play it safe here - if (requireAppStoreEnabled) - { - result = new PluginInfo[] { }; - } - } - + // TODO cvium + var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); +// var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value; +// +// // Don't fail just on account of image url's +// try +// { +// var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None)); +// +// foreach (var plugin in result) +// { +// var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && string.Equals(i.guid.Replace("-", string.Empty), plugin.Id.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase)); +// +// if (pkg != null) +// { +// plugin.ImageUrl = pkg.thumbImage; +// } +// } +// +// if (requireAppStoreEnabled) +// { +// result = result +// .Where(plugin => +// { +// var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && new Guid(plugin.Id).Equals(new Guid(i.guid))); +// return pkg != null && pkg.enableInAppStore; +// +// }) +// .ToArray(); +// } +// } +// catch (Exception ex) +// { +// Logger.LogError(ex, "Error getting plugin list"); +// // Play it safe here +// if (requireAppStoreEnabled) +// { +// result = new PluginInfo[] { }; +// } +// } return ToOptimizedResult(result); } @@ -256,41 +174,6 @@ namespace MediaBrowser.Api return ToOptimizedResult(plugin.Configuration); } - /// - /// Gets the specified request. - /// - /// The request. - /// System.Object. - public async Task Get(GetPluginSecurityInfo request) - { - var result = new PluginSecurityInfo - { - IsMBSupporter = await _securityManager.IsSupporter().ConfigureAwait(false), - SupporterKey = _securityManager.SupporterKey - }; - - return ToOptimizedResult(result); - } - - /// - /// Post app store sale - /// - /// - /// - public Task Post(RegisterAppstoreSale request) - { - return _securityManager.RegisterAppStoreSale(request.Parameters); - } - - /// - /// Posts the specified request. - /// - /// The request. - public Task Post(UpdatePluginSecurityInfo request) - { - return _securityManager.UpdateSupporterKey(request.SupporterKey); - } - /// /// Posts the specified request. /// diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 52e14dbcc9..c2c2386ac4 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Security; using MediaBrowser.Controller; using MediaBrowser.Controller.Net; using MediaBrowser.Model.System; @@ -100,8 +99,6 @@ namespace MediaBrowser.Api.System private readonly INetworkManager _network; - private readonly ISecurityManager _security; - /// /// Initializes a new instance of the class. /// @@ -109,13 +106,12 @@ namespace MediaBrowser.Api.System /// The application paths. /// The file system. /// jsonSerializer - public SystemService(IServerApplicationHost appHost, IApplicationPaths appPaths, IFileSystem fileSystem, INetworkManager network, ISecurityManager security) + public SystemService(IServerApplicationHost appHost, IApplicationPaths appPaths, IFileSystem fileSystem, INetworkManager network) { _appHost = appHost; _appPaths = appPaths; _fileSystem = fileSystem; _network = network; - _security = security; } public object Post(PingSystem request) diff --git a/MediaBrowser.Common/Security/IRequiresRegistration.cs b/MediaBrowser.Common/Security/IRequiresRegistration.cs deleted file mode 100644 index 7b1667c2e2..0000000000 --- a/MediaBrowser.Common/Security/IRequiresRegistration.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Security -{ - public interface IRequiresRegistration - { - /// - /// Load all registration information required for this entity. - /// Your class should re-load all MBRegistrationRecords when this is called even if they were - /// previously loaded. - /// - /// - Task LoadRegistrationInfoAsync(); - } -} diff --git a/MediaBrowser.Common/Security/ISecurityManager.cs b/MediaBrowser.Common/Security/ISecurityManager.cs deleted file mode 100644 index b63a9efd09..0000000000 --- a/MediaBrowser.Common/Security/ISecurityManager.cs +++ /dev/null @@ -1,32 +0,0 @@ -using MediaBrowser.Model.Entities; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Security -{ - public interface ISecurityManager - { - /// - /// Gets a value indicating whether this instance is MB supporter. - /// - /// true if this instance is MB supporter; otherwise, false. - Task IsSupporter(); - - /// - /// Gets or sets the supporter key. - /// - /// The supporter key. - string SupporterKey { get; } - - /// - /// Gets the registration status. Overload to support existing plug-ins. - /// - Task GetRegistrationStatus(string feature); - - /// - /// Register and app store sale with our back-end - /// - /// Json parameters to pass to admin server - Task RegisterAppStoreSale(string parameters); - Task UpdateSupporterKey(string newValue); - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/Security/PaymentRequiredException.cs b/MediaBrowser.Common/Security/PaymentRequiredException.cs deleted file mode 100644 index 27b3e69613..0000000000 --- a/MediaBrowser.Common/Security/PaymentRequiredException.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace MediaBrowser.Common.Security -{ - public class PaymentRequiredException : Exception - { - } -} diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index dab38b27c2..a3e0277d9a 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -49,9 +49,7 @@ namespace MediaBrowser.Common.Updates /// The application version. /// Task{List{PackageInfo}}. Task> GetAvailablePackages(CancellationToken cancellationToken, - bool withRegistration = true, - string packageType = null, - Version applicationVersion = null); + bool withRegistration = true, string packageType = null, Version applicationVersion = null); /// /// Gets all available packages from a static resource. diff --git a/MediaBrowser.Model/Entities/MBRegistrationRecord.cs b/MediaBrowser.Model/Entities/MBRegistrationRecord.cs deleted file mode 100644 index 00176fb344..0000000000 --- a/MediaBrowser.Model/Entities/MBRegistrationRecord.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace MediaBrowser.Model.Entities -{ - public class MBRegistrationRecord - { - public DateTime ExpirationDate { get; set; } - public bool IsRegistered { get; set; } - public bool RegChecked { get; set; } - public bool RegError { get; set; } - public bool TrialVersion { get; set; } - public bool IsValid { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/Entities/PluginSecurityInfo.cs b/MediaBrowser.Model/Entities/PluginSecurityInfo.cs deleted file mode 100644 index 5cab55013e..0000000000 --- a/MediaBrowser.Model/Entities/PluginSecurityInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ - -namespace MediaBrowser.Model.Entities -{ - /// - /// Class PluginSecurityInfo - /// - public class PluginSecurityInfo - { - /// - /// Gets or sets the supporter key. - /// - /// The supporter key. - public string SupporterKey { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is MB supporter. - /// - /// true if this instance is MB supporter; otherwise, false. - public bool IsMBSupporter { get; set; } - } -} From 4a03ac40220c26e4c08788a6f9434e0f6472bf9d Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sat, 5 Jan 2019 00:25:34 +0100 Subject: [PATCH 36/45] mock the registration endpoint since livetv etc. still uses it --- MediaBrowser.Api/PluginService.cs | 32 +++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 75defa998b..477f916dea 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -76,7 +76,22 @@ namespace MediaBrowser.Api public Stream RequestStream { get; set; } } - + [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] + [Authenticated] + public class GetRegistration : IReturn + { + [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Name { get; set; } + } + + public class RegistrationInfo + { + public string Name { get; set; } + public DateTime ExpirationDate { get; set; } + public bool IsTrial { get; set; } + public bool IsRegistered { get; set; } + } + /// /// Class PluginsService /// @@ -109,7 +124,20 @@ namespace MediaBrowser.Api _deviceManager = deviceManager; _jsonSerializer = jsonSerializer; } - + + + public async Task Get(GetRegistration request) + { + var info = new RegistrationInfo + { + ExpirationDate = DateTime.Now.AddYears(100), + IsRegistered = true, + IsTrial = false, + Name = request.Name + }; + + return ToOptimizedResult(info); + } /// /// Gets the specified request. From d707e969fa51363183853162440bdea7c403ef5e Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sat, 5 Jan 2019 00:29:00 +0100 Subject: [PATCH 37/45] Added some todos --- MediaBrowser.Api/PluginService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 477f916dea..de872f8b69 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -75,7 +75,8 @@ namespace MediaBrowser.Api /// The request stream. public Stream RequestStream { get; set; } } - + + //TODO cvium delete this [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] [Authenticated] public class GetRegistration : IReturn @@ -84,6 +85,7 @@ namespace MediaBrowser.Api public string Name { get; set; } } + //TODO cvium delete this public class RegistrationInfo { public string Name { get; set; } @@ -125,7 +127,7 @@ namespace MediaBrowser.Api _jsonSerializer = jsonSerializer; } - + //TODO cvium delete this public async Task Get(GetRegistration request) { var info = new RegistrationInfo From 19319e8eb6561e776707848318ec4799128d84e7 Mon Sep 17 00:00:00 2001 From: hawken Date: Fri, 4 Jan 2019 23:47:49 +0000 Subject: [PATCH 38/45] Remove MBLicenseFile --- .../Security/MBLicenseFile.cs | 204 ------------------ 1 file changed, 204 deletions(-) delete mode 100644 Emby.Server.Implementations/Security/MBLicenseFile.cs diff --git a/Emby.Server.Implementations/Security/MBLicenseFile.cs b/Emby.Server.Implementations/Security/MBLicenseFile.cs deleted file mode 100644 index fc1c1f0bf9..0000000000 --- a/Emby.Server.Implementations/Security/MBLicenseFile.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.IO; - -namespace Emby.Server.Implementations.Security -{ - internal class MBLicenseFile - { - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - private readonly ICryptoProvider _cryptographyProvider; - - public string RegKey - { - get => _regKey; - set - { - _updateRecords.Clear(); - _regKey = value; - } - } - - private string Filename => Path.Combine(_appPaths.ConfigurationDirectoryPath, "mb.lic"); - - private readonly ConcurrentDictionary _updateRecords = new ConcurrentDictionary(); - private readonly object _fileLock = new object(); - private string _regKey; - - public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) - { - _appPaths = appPaths; - _fileSystem = fileSystem; - _cryptographyProvider = cryptographyProvider; - - Load(); - } - - private void SetUpdateRecord(Guid key, FeatureRegInfo value) - { - _updateRecords.AddOrUpdate(key, value, (k, v) => value); - } - - private Guid GetKey(string featureId) - { - return new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId))); - } - - public void AddRegCheck(string featureId, DateTime expirationDate) - { - var key = GetKey(featureId); - var value = new FeatureRegInfo - { - ExpirationDate = expirationDate, - LastChecked = DateTime.UtcNow - }; - - SetUpdateRecord(key, value); - Save(); - } - - public void RemoveRegCheck(string featureId) - { - var key = GetKey(featureId); - FeatureRegInfo val; - - _updateRecords.TryRemove(key, out val); - - Save(); - } - - public FeatureRegInfo GetRegInfo(string featureId) - { - var key = GetKey(featureId); - FeatureRegInfo info = null; - _updateRecords.TryGetValue(key, out info); - - if (info == null) - { - return null; - } - - // guard agains people just putting a large number in the file - return info.LastChecked < DateTime.UtcNow ? info : null; - } - - private void Load() - { - string[] contents = null; - var licenseFile = Filename; - lock (_fileLock) - { - try - { - contents = _fileSystem.ReadAllLines(licenseFile); - } - catch (FileNotFoundException) - { - lock (_fileLock) - { - _fileSystem.WriteAllBytes(licenseFile, Array.Empty()); - } - } - catch (IOException) - { - lock (_fileLock) - { - _fileSystem.WriteAllBytes(licenseFile, Array.Empty()); - } - } - } - if (contents != null && contents.Length > 0) - { - //first line is reg key - RegKey = contents[0]; - - //next is legacy key - if (contents.Length > 1) - { - // Don't need this anymore - } - - //the rest of the lines should be pairs of features and timestamps - for (var i = 2; i < contents.Length; i = i + 2) - { - var line = contents[i]; - if (string.IsNullOrWhiteSpace(line)) - { - continue; - } - - Guid feat; - if (Guid.TryParse(line, out feat)) - { - var lineParts = contents[i + 1].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); - - long ticks; - if (long.TryParse(lineParts[0], out ticks)) - { - var info = new FeatureRegInfo - { - LastChecked = new DateTime(ticks) - }; - - if (lineParts.Length > 1 && long.TryParse(lineParts[1], out ticks)) - { - info.ExpirationDate = new DateTime(ticks); - } - - SetUpdateRecord(feat, info); - } - } - } - } - } - - public void Save() - { - //build our array - var lines = new List - { - RegKey, - - // Legacy key - string.Empty - }; - - foreach (var pair in _updateRecords - .ToList()) - { - lines.Add(pair.Key.ToString()); - - var dateLine = pair.Value.LastChecked.Ticks.ToString(CultureInfo.InvariantCulture) + "|" + - pair.Value.ExpirationDate.Ticks.ToString(CultureInfo.InvariantCulture); - - lines.Add(dateLine); - } - - var licenseFile = Filename; - _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(licenseFile)); - lock (_fileLock) - { - _fileSystem.WriteAllLines(licenseFile, lines); - } - } - } - - internal class FeatureRegInfo - { - public DateTime ExpirationDate { get; set; } - public DateTime LastChecked { get; set; } - - public FeatureRegInfo() - { - ExpirationDate = DateTime.MinValue; - } - } -} From 801726ce3827c0f1fe5be1894b6f5b1a7a2bab80 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sat, 5 Jan 2019 08:02:39 +0100 Subject: [PATCH 39/45] readded some registration endpoints --- MediaBrowser.Api/PluginService.cs | 98 +++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index de872f8b69..370cec58d7 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -76,7 +76,8 @@ namespace MediaBrowser.Api public Stream RequestStream { get; set; } } - //TODO cvium delete this + //TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins, + // delete all these registration endpoints. They are only kept for compatibility. [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] [Authenticated] public class GetRegistration : IReturn @@ -85,7 +86,33 @@ namespace MediaBrowser.Api public string Name { get; set; } } - //TODO cvium delete this + /// + /// Class GetPluginSecurityInfo + /// + [Route("/Plugins/SecurityInfo", "GET", Summary = "Gets plugin registration information", IsHidden = true)] + [Authenticated] + public class GetPluginSecurityInfo : IReturn + { + } + + /// + /// Class UpdatePluginSecurityInfo + /// + [Route("/Plugins/SecurityInfo", "POST", Summary = "Updates plugin registration information", IsHidden = true)] + [Authenticated(Roles = "Admin")] + public class UpdatePluginSecurityInfo : PluginSecurityInfo, IReturnVoid + { + } + + [Route("/Plugins/RegistrationRecords/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] + [Authenticated] + public class GetRegistrationStatus + { + [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Name { get; set; } + } + + // TODO these two classes are only kept for compability with paid plugins and should be removed public class RegistrationInfo { public string Name { get; set; } @@ -94,6 +121,21 @@ namespace MediaBrowser.Api public bool IsRegistered { get; set; } } + public class MBRegistrationRecord + { + public DateTime ExpirationDate { get; set; } + public bool IsRegistered { get; set; } + public bool RegChecked { get; set; } + public bool RegError { get; set; } + public bool TrialVersion { get; set; } + public bool IsValid { get; set; } + } + + public class PluginSecurityInfo + { + public string SupporterKey { get; set; } + public bool IsMBSupporter { get; set; } + } /// /// Class PluginsService /// @@ -127,7 +169,26 @@ namespace MediaBrowser.Api _jsonSerializer = jsonSerializer; } - //TODO cvium delete this + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public async Task Get(GetRegistrationStatus request) + { + var record = new MBRegistrationRecord + { + IsRegistered = true, + RegChecked = true, + TrialVersion = false, + IsValid = true, + RegError = false + }; + + return ToOptimizedResult(record); + } + + //TODO this function is only kept for compatibility and should be removed once paid plugins break public async Task Get(GetRegistration request) { var info = new RegistrationInfo @@ -140,7 +201,7 @@ namespace MediaBrowser.Api return ToOptimizedResult(info); } - + /// /// Gets the specified request. /// @@ -148,7 +209,7 @@ namespace MediaBrowser.Api /// System.Object. public async Task Get(GetPlugins request) { - // TODO cvium + // TODO This code can be reused for a proper Jellyfin plugin store (maybe). Remove/reuse when decided. var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); // var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value; // @@ -203,7 +264,32 @@ namespace MediaBrowser.Api return ToOptimizedResult(plugin.Configuration); } - + + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public async Task Get(GetPluginSecurityInfo request) + { + var result = new PluginSecurityInfo + { + IsMBSupporter = true, + SupporterKey = "IAmTotallyLegit" + }; + + return ToOptimizedResult(result); + } + + /// + /// Posts the specified request. + /// + /// The request. + public Task Post(UpdatePluginSecurityInfo request) + { + return Task.CompletedTask; + } + /// /// Posts the specified request. /// From e0e5a487c3b10c3f248efe1a7063b18b8c2a9402 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sat, 5 Jan 2019 08:18:44 +0100 Subject: [PATCH 40/45] removed commented code --- MediaBrowser.Api/PluginService.cs | 75 ++++++++----------------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 370cec58d7..17822fb54f 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -75,7 +75,7 @@ namespace MediaBrowser.Api /// The request stream. public Stream RequestStream { get; set; } } - + //TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins, // delete all these registration endpoints. They are only kept for compatibility. [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] @@ -85,7 +85,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Name { get; set; } } - + /// /// Class GetPluginSecurityInfo /// @@ -94,7 +94,7 @@ namespace MediaBrowser.Api public class GetPluginSecurityInfo : IReturn { } - + /// /// Class UpdatePluginSecurityInfo /// @@ -103,7 +103,7 @@ namespace MediaBrowser.Api public class UpdatePluginSecurityInfo : PluginSecurityInfo, IReturnVoid { } - + [Route("/Plugins/RegistrationRecords/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] [Authenticated] public class GetRegistrationStatus @@ -111,7 +111,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Name { get; set; } } - + // TODO these two classes are only kept for compability with paid plugins and should be removed public class RegistrationInfo { @@ -120,7 +120,7 @@ namespace MediaBrowser.Api public bool IsTrial { get; set; } public bool IsRegistered { get; set; } } - + public class MBRegistrationRecord { public DateTime ExpirationDate { get; set; } @@ -130,7 +130,7 @@ namespace MediaBrowser.Api public bool TrialVersion { get; set; } public bool IsValid { get; set; } } - + public class PluginSecurityInfo { public string SupporterKey { get; set; } @@ -168,7 +168,7 @@ namespace MediaBrowser.Api _deviceManager = deviceManager; _jsonSerializer = jsonSerializer; } - + /// /// Gets the specified request. /// @@ -184,13 +184,13 @@ namespace MediaBrowser.Api IsValid = true, RegError = false }; - + return ToOptimizedResult(record); } - + //TODO this function is only kept for compatibility and should be removed once paid plugins break public async Task Get(GetRegistration request) - { + { var info = new RegistrationInfo { ExpirationDate = DateTime.Now.AddYears(100), @@ -198,10 +198,10 @@ namespace MediaBrowser.Api IsTrial = false, Name = request.Name }; - + return ToOptimizedResult(info); } - + /// /// Gets the specified request. /// @@ -209,46 +209,7 @@ namespace MediaBrowser.Api /// System.Object. public async Task Get(GetPlugins request) { - // TODO This code can be reused for a proper Jellyfin plugin store (maybe). Remove/reuse when decided. - var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); -// var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value; -// -// // Don't fail just on account of image url's -// try -// { -// var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None)); -// -// foreach (var plugin in result) -// { -// var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && string.Equals(i.guid.Replace("-", string.Empty), plugin.Id.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase)); -// -// if (pkg != null) -// { -// plugin.ImageUrl = pkg.thumbImage; -// } -// } -// -// if (requireAppStoreEnabled) -// { -// result = result -// .Where(plugin => -// { -// var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && new Guid(plugin.Id).Equals(new Guid(i.guid))); -// return pkg != null && pkg.enableInAppStore; -// -// }) -// .ToArray(); -// } -// } -// catch (Exception ex) -// { -// Logger.LogError(ex, "Error getting plugin list"); -// // Play it safe here -// if (requireAppStoreEnabled) -// { -// result = new PluginInfo[] { }; -// } -// } + var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); return ToOptimizedResult(result); } @@ -264,7 +225,7 @@ namespace MediaBrowser.Api return ToOptimizedResult(plugin.Configuration); } - + /// /// Gets the specified request. /// @@ -277,10 +238,10 @@ namespace MediaBrowser.Api IsMBSupporter = true, SupporterKey = "IAmTotallyLegit" }; - + return ToOptimizedResult(result); } - + /// /// Posts the specified request. /// @@ -289,7 +250,7 @@ namespace MediaBrowser.Api { return Task.CompletedTask; } - + /// /// Posts the specified request. /// From 256e6dc1952e25b9d57a8bafba2edad88209c769 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Sat, 5 Jan 2019 08:21:17 +0100 Subject: [PATCH 41/45] removed more dead code --- Emby.Server.Implementations/Security/RegRecord.cs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 Emby.Server.Implementations/Security/RegRecord.cs diff --git a/Emby.Server.Implementations/Security/RegRecord.cs b/Emby.Server.Implementations/Security/RegRecord.cs deleted file mode 100644 index d484085d3f..0000000000 --- a/Emby.Server.Implementations/Security/RegRecord.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Emby.Server.Implementations.Security -{ - class RegRecord - { - public string featId { get; set; } - public bool registered { get; set; } - public DateTime expDate { get; set; } - public string key { get; set; } - } -} \ No newline at end of file From 0e422a33d698577a32e0a8a9058d2f7b9802b3b2 Mon Sep 17 00:00:00 2001 From: cvium Date: Mon, 7 Jan 2019 20:10:26 +0100 Subject: [PATCH 42/45] Some code style clean up --- .../LiveTv/EmbyTV/EmbyTV.cs | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2c671f5105..97110ab1de 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -452,18 +452,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public ChannelInfo GetChannelByNumber(string number) { - ChannelInfo result = null; - - ChannelsByNumber.TryGetValue(number, out result); + ChannelsByNumber.TryGetValue(number, out var result); return result; } public ChannelInfo GetChannelByName(string name) { - ChannelInfo result = null; - - ChannelsByName.TryGetValue(name, out result); + ChannelsByName.TryGetValue(name, out var result); return result; } @@ -2396,10 +2392,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } _timerProvider.Add(timer); - if (TimerCreated != null) - { - TimerCreated(this, new GenericEventArgs(timer)); - } + TimerCreated?.Invoke(this, new GenericEventArgs(timer)); } else { @@ -2508,9 +2501,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV if (string.IsNullOrWhiteSpace(channelId) && !parent.ChannelId.Equals(Guid.Empty)) { - LiveTvChannel channel; - - if (!tempChannelCache.TryGetValue(parent.ChannelId, out channel)) + if (!tempChannelCache.TryGetValue(parent.ChannelId, out var channel)) { channel = _libraryManager.GetItemList(new InternalItemsQuery { @@ -2569,9 +2560,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV if (!programInfo.ChannelId.Equals(Guid.Empty)) { - LiveTvChannel channel; - - if (!tempChannelCache.TryGetValue(programInfo.ChannelId, out channel)) + if (!tempChannelCache.TryGetValue(programInfo.ChannelId, out var channel)) { channel = _libraryManager.GetItemList(new InternalItemsQuery { @@ -2769,15 +2758,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { var configuredDevice = configuredDevices.FirstOrDefault(i => string.Equals(i.DeviceId, device.DeviceId, StringComparison.OrdinalIgnoreCase)); - if (configuredDevice != null) + if (configuredDevice != null && !string.Equals(device.Url, configuredDevice.Url, StringComparison.OrdinalIgnoreCase)) { - if (!string.Equals(device.Url, configuredDevice.Url, StringComparison.OrdinalIgnoreCase)) - { - _logger.LogInformation("Tuner url has changed from {0} to {1}", configuredDevice.Url, device.Url); + _logger.LogInformation("Tuner url has changed from {0} to {1}", configuredDevice.Url, device.Url); - configuredDevice.Url = device.Url; - await _liveTvManager.SaveTunerHost(configuredDevice).ConfigureAwait(false); - } + configuredDevice.Url = device.Url; + await _liveTvManager.SaveTunerHost(configuredDevice).ConfigureAwait(false); } } } From 22a64f37f54db9ae39b9265bcf24858377b74d14 Mon Sep 17 00:00:00 2001 From: cvium Date: Mon, 7 Jan 2019 20:35:26 +0100 Subject: [PATCH 43/45] More cleaning --- .../LiveTv/EmbyTV/EmbyTV.cs | 70 +++++++++---------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 97110ab1de..b787e8f0f9 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -2394,45 +2394,41 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV TimerCreated?.Invoke(this, new GenericEventArgs(timer)); } - else + // Only update if not currently active - test both new timer and existing in case Id's are different + // Id's could be different if the timer was created manually prior to series timer creation + else if (!_activeRecordings.TryGetValue(timer.Id, out _) && !_activeRecordings.TryGetValue(existingTimer.Id, out _)) { - // Only update if not currently active - test both new timer and existing in case Id's are different - // Id's could be different if the timer was created manually prior to series timer creation - ActiveRecordingInfo activeRecordingInfo; - if (!_activeRecordings.TryGetValue(timer.Id, out activeRecordingInfo) && !_activeRecordings.TryGetValue(existingTimer.Id, out activeRecordingInfo)) + UpdateExistingTimerWithNewMetadata(existingTimer, timer); + + // Needed by ShouldCancelTimerForSeriesTimer + timer.IsManual = existingTimer.IsManual; + + if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) { - UpdateExistingTimerWithNewMetadata(existingTimer, timer); - - // Needed by ShouldCancelTimerForSeriesTimer - timer.IsManual = existingTimer.IsManual; - - if (ShouldCancelTimerForSeriesTimer(seriesTimer, timer)) - { - existingTimer.Status = RecordingStatus.Cancelled; - } - else if (!existingTimer.IsManual) - { - existingTimer.Status = RecordingStatus.New; - } - - if (existingTimer.Status != RecordingStatus.Cancelled) - { - enabledTimersForSeries.Add(existingTimer); - } - - if (updateTimerSettings) - { - existingTimer.KeepUntil = seriesTimer.KeepUntil; - existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired; - existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired; - existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds; - existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds; - existingTimer.Priority = seriesTimer.Priority; - } - - existingTimer.SeriesTimerId = seriesTimer.Id; - _timerProvider.Update(existingTimer); + existingTimer.Status = RecordingStatus.Cancelled; } + else if (!existingTimer.IsManual) + { + existingTimer.Status = RecordingStatus.New; + } + + if (existingTimer.Status != RecordingStatus.Cancelled) + { + enabledTimersForSeries.Add(existingTimer); + } + + if (updateTimerSettings) + { + existingTimer.KeepUntil = seriesTimer.KeepUntil; + existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired; + existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired; + existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds; + existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds; + existingTimer.Priority = seriesTimer.Priority; + } + + existingTimer.SeriesTimerId = seriesTimer.Id; + _timerProvider.Update(existingTimer); } } @@ -2760,7 +2756,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV if (configuredDevice != null && !string.Equals(device.Url, configuredDevice.Url, StringComparison.OrdinalIgnoreCase)) { - _logger.LogInformation("Tuner url has changed from {0} to {1}", configuredDevice.Url, device.Url); + _logger.LogInformation("Tuner url has changed from {PreviousUrl} to {NewUrl}", configuredDevice.Url, device.Url); configuredDevice.Url = device.Url; await _liveTvManager.SaveTunerHost(configuredDevice).ConfigureAwait(false); From e5ffa45dbe05773b7c2ac20019eac98be2797a3b Mon Sep 17 00:00:00 2001 From: cvium Date: Sat, 12 Jan 2019 19:52:59 +0100 Subject: [PATCH 44/45] more descriptive TODO --- Emby.Server.Implementations/Updates/InstallationManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 27ec476cc1..d4653281fc 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -125,7 +125,7 @@ namespace Emby.Server.Implementations.Updates IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, - IJsonSerializer jsonSerializer, + IJsonSerializer jsonSerializer, IServerConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, @@ -169,7 +169,7 @@ namespace Emby.Server.Implementations.Updates string packageType = null, Version applicationVersion = null) { - // TODO cvium + // TODO cvium: when plugins get back this would need to be fixed // var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); return new List(); //FilterPackages(packages, packageType, applicationVersion); From 99acf83dfafedd3f426cf3ddf0de8bf58cdea86d Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Mon, 14 Jan 2019 22:57:04 +0100 Subject: [PATCH 45/45] Add cvium to CONTRIBUTORS --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c88f4cbcd4..f33f48fb33 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,6 +12,7 @@ - [sparky8251](https://github.com/sparky8251) - [LeoVerto](https://github.com/LeoVerto) - [grafixeyehero](https://github.com/grafixeyehero) + - [cvium](https://github.com/cvium) # Emby Contributors