From dfe72302307feb6e2f6065fd76454786a1b50bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 20 Feb 2023 03:11:16 +0100 Subject: [PATCH 01/25] Use stdeb to build deb packages from Python packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately stdeb has not been updated yet to use pyproject.toml files and still require a setup.py file. Fortunately since setuptools 61.0 the configuration from the pyproject.toml file takes precedence and a dummy setup.py file loads the configuration from the pyproject.toml file. Signed-off-by: Daniel Calviño Sánchez --- .gitignore | 6 ++++++ recording/Makefile | 25 +++++++++++++++++++++++++ recording/pyproject.toml | 6 ++++++ recording/setup.py | 7 +++++++ 4 files changed, 44 insertions(+) create mode 100644 recording/Makefile create mode 100644 recording/setup.py diff --git a/.gitignore b/.gitignore index a6a936adcba..5ed425da0ad 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,9 @@ # JetBrains Fleet settings /.fleet + +# Recording server packages +/recording/deb_dist +/recording/dist/ +/recording/nextcloud-talk-recording-*.tar.gz +/recording/src/nextcloud_talk_recording.egg-info/ diff --git a/recording/Makefile b/recording/Makefile new file mode 100644 index 00000000000..4774e0a30a3 --- /dev/null +++ b/recording/Makefile @@ -0,0 +1,25 @@ +# +# @copyright Copyright (c) 2023, Daniel Calviño Sánchez (danxuliu@gmail.com) +# +# @license GNU AGPL version 3 or any later version +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +build-package-deb: + python3 -m pip install "setuptools >= 61.0" + # Since the 60.0.0 release, Setuptools includes a local, vendored copy of + # distutils; this copy does not seem to work with stdeb, so it needs to be + # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". + SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command bdist_deb diff --git a/recording/pyproject.toml b/recording/pyproject.toml index 7260220797a..7835f57996a 100644 --- a/recording/pyproject.toml +++ b/recording/pyproject.toml @@ -1,6 +1,9 @@ [project] name = "nextcloud-talk-recording" description = "Recording server for Nextcloud Talk" +authors = [ + { name = "Nextcloud Talk Team" }, +] license = {text = "GNU AGPLv3+"} classifiers = [ "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", @@ -15,5 +18,8 @@ dependencies = [ ] dynamic = ["version"] +[project.urls] +repository = "https://github.com/nextcloud/spreed" + [tool.setuptools.dynamic] version = {attr = "nextcloud.talk.recording.__version__"} diff --git a/recording/setup.py b/recording/setup.py new file mode 100644 index 00000000000..7c3446b9b69 --- /dev/null +++ b/recording/setup.py @@ -0,0 +1,7 @@ +# Dummy setup.py file to be used by stdeb; setuptools >= 61.0 must be used to +# get the proper configuration from the pyproject.toml file. + +from setuptools import setup + +setup( +) From 27898688b7b3f04946607d09a81578258c412819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 20 Feb 2023 03:15:19 +0100 Subject: [PATCH 02/25] Add basic README.md file as it is expected by Python sdist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 recording/README.md diff --git a/recording/README.md b/recording/README.md new file mode 100644 index 00000000000..48f7f485d27 --- /dev/null +++ b/recording/README.md @@ -0,0 +1,7 @@ +# Nextcloud Talk Recording Server + +This is the official recording server to be used with Nextcloud Talk (https://github.com/nextcloud/spreed). + +It requires the standalone signaling server for Nextcloud Talk (https://github.com/strukturag/nextcloud-spreed-signaling). + +The recording server only provides an HTTP API. It is expected that TLS termination will be provided by an additional component, like a reverse proxy. From 5862e5b60f988900143ee0f8516bb9eab3ced710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 15 Mar 2023 15:10:46 +0100 Subject: [PATCH 03/25] Set parameters in setup.py not properly read from pyproject.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/setup.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/recording/setup.py b/recording/setup.py index 7c3446b9b69..d55878a2e37 100644 --- a/recording/setup.py +++ b/recording/setup.py @@ -4,4 +4,11 @@ from setuptools import setup setup( + # pyproject.toml uses different keywords that are not properly converted to + # the old ones, so they need to be explicitly set here to be used by stdeb. + # "author" can not be set without "author_email". Moreover, if the email was + # also set in pyproject.toml it could not be set here either, as due to how + # the parameters are internally handled by stdeb it would end mixing the + # author set here with the author and email set in pyproject.toml. + url = "https://github.com/nextcloud/spreed", ) From 05d25fc9a9e60a7ae209405cd2c825c1adc6ecdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 01:56:33 +0100 Subject: [PATCH 04/25] Move packaging related files to its own directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using the main build command now a Python package is explicitly created and extracted, and the Debian package is generated from that extracted package to be able to adjust some things (like copying a "setup.py" file used only for packaging without having to include it in the main sources). Unfortunately not everything can be done under the "packaging" directory, as the "__pycache__" and "egg-info" directories are created in the source directory when the Python package is created. Signed-off-by: Daniel Calviño Sánchez --- .gitignore | 5 ++--- recording/{ => packaging}/Makefile | 18 +++++++++++++++++- recording/{ => packaging}/setup.py | 0 3 files changed, 19 insertions(+), 4 deletions(-) rename recording/{ => packaging}/Makefile (54%) rename recording/{ => packaging}/setup.py (100%) diff --git a/.gitignore b/.gitignore index 5ed425da0ad..fe43b147e13 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,6 @@ /.fleet # Recording server packages -/recording/deb_dist -/recording/dist/ -/recording/nextcloud-talk-recording-*.tar.gz +/recording/packaging/nextcloud-talk-recording-* +/recording/src/nextcloud/talk/recording/__pycache__/ /recording/src/nextcloud_talk_recording.egg-info/ diff --git a/recording/Makefile b/recording/packaging/Makefile similarity index 54% rename from recording/Makefile rename to recording/packaging/Makefile index 4774e0a30a3..534d5ec5cca 100644 --- a/recording/Makefile +++ b/recording/packaging/Makefile @@ -17,9 +17,25 @@ # along with this program. If not, see . # +NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") + build-package-deb: python3 -m pip install "setuptools >= 61.0" + + # Build a source Python package + python3 -m build --sdist --outdir . ../ + + # Extract source Python package + tar --extract --gzip --file nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION).tar.gz + + # Add extra files needed to create Debian packages: + # - setup.py: legacy setup file needed for stdeb (also needed in the + # regenerated Python package, as stdeb is invoked through it to create the + # source Debian package). + cp setup.py nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + + # Build a source Debian package and then, from it, a binary Debian package # Since the 60.0.0 release, Setuptools includes a local, vendored copy of # distutils; this copy does not seem to work with stdeb, so it needs to be # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". - SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command bdist_deb + cd nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc bdist_deb diff --git a/recording/setup.py b/recording/packaging/setup.py similarity index 100% rename from recording/setup.py rename to recording/packaging/setup.py From 2c2ee8c27d3d08e0ca546d28b85fb0c5d8526c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 20 Feb 2023 03:17:15 +0100 Subject: [PATCH 05/25] Use strict dependencies for Debian packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Python dependencies are translated into Debian packages by dh_python3. As described in its man page, by default dh_python3 discards the version information in the Python dependencies, so those dependencies that need a strict version have to be explicitly overriden in a "debian/py3dist-overrides" file. That file is not included by default in Python source packages, so the full "debian" directory is explicitly included using a MANIFEST.in file. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/MANIFEST.in | 1 + recording/packaging/Makefile | 9 +++++++++ recording/packaging/debian/py3dist-overrides | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 recording/packaging/MANIFEST.in create mode 100644 recording/packaging/debian/py3dist-overrides diff --git a/recording/packaging/MANIFEST.in b/recording/packaging/MANIFEST.in new file mode 100644 index 00000000000..b3009faaf41 --- /dev/null +++ b/recording/packaging/MANIFEST.in @@ -0,0 +1 @@ +graft debian diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 534d5ec5cca..357b3fce53b 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -29,9 +29,18 @@ build-package-deb: tar --extract --gzip --file nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION).tar.gz # Add extra files needed to create Debian packages: + # - debian/py3dist-overrides: Python dependencies to Debian dependencies for + # dh_python3 (also needed in the regenerated Python package, as it is + # needed in the Debian package). + # - MANIFEST.in: the source package is regenerated to include the extra + # files needed for the Debian package; MANIFEST.in explicitly adds those + # files not included by default in a Python package (so setup.py does not + # need to be included in MANIFEST.in, but debian/py3dist-overrides does). # - setup.py: legacy setup file needed for stdeb (also needed in the # regenerated Python package, as stdeb is invoked through it to create the # source Debian package). + cp --recursive debian nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp MANIFEST.in nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ cp setup.py nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ # Build a source Debian package and then, from it, a binary Debian package diff --git a/recording/packaging/debian/py3dist-overrides b/recording/packaging/debian/py3dist-overrides new file mode 100644 index 00000000000..6891183b900 --- /dev/null +++ b/recording/packaging/debian/py3dist-overrides @@ -0,0 +1,3 @@ +pulsectl python3-pulsectl +pyvirtualdisplay python3-pyvirtualdisplay (>= 2.0) +selenium python3-selenium (>= 4.6.0) From 65e91277fb85e88fba5b91ec7de2f0ff0ec402ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 24 Feb 2023 15:18:11 +0100 Subject: [PATCH 06/25] Add non Python dependencies to Debian package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 4 ++++ recording/packaging/stdeb.cfg | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 recording/packaging/stdeb.cfg diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 357b3fce53b..738957adb2e 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -39,9 +39,13 @@ build-package-deb: # - setup.py: legacy setup file needed for stdeb (also needed in the # regenerated Python package, as stdeb is invoked through it to create the # source Debian package). + # - stdeb.cfg: additional configuration for stdeb (not needed in the + # regenerated Python package, as stdeb loads it before changing to the + # uncompressed source Python package). cp --recursive debian nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ cp MANIFEST.in nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ cp setup.py nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp stdeb.cfg nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ # Build a source Debian package and then, from it, a binary Debian package # Since the 60.0.0 release, Setuptools includes a local, vendored copy of diff --git a/recording/packaging/stdeb.cfg b/recording/packaging/stdeb.cfg new file mode 100644 index 00000000000..36bb6c18b8e --- /dev/null +++ b/recording/packaging/stdeb.cfg @@ -0,0 +1,2 @@ +[DEFAULT] +Depends3: ffmpeg, firefox, firefox-geckodriver, pulseaudio, xvfb From 7f4ce090741f2bc26bad3f2afc517275532c3a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 12:19:58 +0100 Subject: [PATCH 07/25] Create build files in their own directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default the build files will be created in the "build" directory, but a different one can be defined when calling make (for example, "make BUILD_DIR=temp"). Signed-off-by: Daniel Calviño Sánchez --- .gitignore | 2 +- recording/packaging/Makefile | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index fe43b147e13..904042c28a2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,6 @@ /.fleet # Recording server packages -/recording/packaging/nextcloud-talk-recording-* +/recording/packaging/build/ /recording/src/nextcloud/talk/recording/__pycache__/ /recording/src/nextcloud_talk_recording.egg-info/ diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 738957adb2e..04fb0a79961 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -17,16 +17,18 @@ # along with this program. If not, see . # +BUILD_DIR ?= build + NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") build-package-deb: python3 -m pip install "setuptools >= 61.0" # Build a source Python package - python3 -m build --sdist --outdir . ../ + python3 -m build --sdist --outdir $(BUILD_DIR) ../ # Extract source Python package - tar --extract --gzip --file nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION).tar.gz + cd $(BUILD_DIR) && tar --extract --gzip --file nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION).tar.gz # Add extra files needed to create Debian packages: # - debian/py3dist-overrides: Python dependencies to Debian dependencies for @@ -42,13 +44,13 @@ build-package-deb: # - stdeb.cfg: additional configuration for stdeb (not needed in the # regenerated Python package, as stdeb loads it before changing to the # uncompressed source Python package). - cp --recursive debian nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp MANIFEST.in nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp setup.py nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp stdeb.cfg nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp --recursive debian $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp MANIFEST.in $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp setup.py $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp stdeb.cfg $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ # Build a source Debian package and then, from it, a binary Debian package # Since the 60.0.0 release, Setuptools includes a local, vendored copy of # distutils; this copy does not seem to work with stdeb, so it needs to be # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". - cd nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc bdist_deb + cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc bdist_deb From 23b04e52dca00362201e4a5edd0278f0a3393dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 13:33:10 +0100 Subject: [PATCH 08/25] Add rule to prevent bulding it again if the package is already built MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 04fb0a79961..2cae08ca276 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -21,7 +21,8 @@ BUILD_DIR ?= build NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") -build-package-deb: +build-package-deb: $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb +$(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb: python3 -m pip install "setuptools >= 61.0" # Build a source Python package From 48fc7669b25fdcc4c1a510ed8b0b5e7360325b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 13:39:33 +0100 Subject: [PATCH 09/25] Copy deb package to specific output directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default the .deb package is created deep in the build directory, so for convenience it is now copied to "build/deb". The output directory is guaranteed to be created when the package is built by using an "order-only" prerequisite, so it will be created if needed, but its modification time will not trigger a rebuilt. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 2cae08ca276..edc590cfa3f 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -21,8 +21,11 @@ BUILD_DIR ?= build NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") -build-package-deb: $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb -$(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb: +$(BUILD_DIR)/deb: + mkdir --parents $(BUILD_DIR)/deb + +build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb +$(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb: | $(BUILD_DIR)/deb python3 -m pip install "setuptools >= 61.0" # Build a source Python package @@ -55,3 +58,6 @@ $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_di # distutils; this copy does not seem to work with stdeb, so it needs to be # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc bdist_deb + + # Copy package to main build directory + cp $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb $(BUILD_DIR)/deb/ From c0310d0e59b06cc8426a0370f3bf757edf06348b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 14:45:52 +0100 Subject: [PATCH 10/25] Include OS version in package name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make possible to keep different packages for different operating system versions in the same repository. The build directory now also takes into account the operating system where it was built to be able to share the same directory in a clean way. Note that it is expected that "/etc/os-release" is available to find out the operating system version. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index edc590cfa3f..3729f9075df 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -17,15 +17,19 @@ # along with this program. If not, see . # -BUILD_DIR ?= build +OS_VERSION ?= $(shell . /etc/os-release 2> /dev/null && echo $$ID$$VERSION_ID) +RELEASE ?= 1 +DEBIAN_VERSION ?= $(RELEASE)~$(OS_VERSION) + +BUILD_DIR ?= build/$(OS_VERSION) NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") $(BUILD_DIR)/deb: mkdir --parents $(BUILD_DIR)/deb -build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb -$(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb: | $(BUILD_DIR)/deb +build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb python3 -m pip install "setuptools >= 61.0" # Build a source Python package @@ -57,7 +61,7 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # Since the 60.0.0 release, Setuptools includes a local, vendored copy of # distutils; this copy does not seem to work with stdeb, so it needs to be # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". - cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc bdist_deb + cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --debian-version $(DEBIAN_VERSION) bdist_deb # Copy package to main build directory - cp $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-1_all.deb $(BUILD_DIR)/deb/ + cp $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/ From 19350fd2052d10293f07201837504ce4b7ed7ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 14:06:45 +0100 Subject: [PATCH 11/25] Move recording server packaging files to its own directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 5 +---- .../packaging/{ => nextcloud-talk-recording}/MANIFEST.in | 0 .../{ => nextcloud-talk-recording}/debian/py3dist-overrides | 0 recording/packaging/{ => nextcloud-talk-recording}/setup.py | 0 recording/packaging/{ => nextcloud-talk-recording}/stdeb.cfg | 0 5 files changed, 1 insertion(+), 4 deletions(-) rename recording/packaging/{ => nextcloud-talk-recording}/MANIFEST.in (100%) rename recording/packaging/{ => nextcloud-talk-recording}/debian/py3dist-overrides (100%) rename recording/packaging/{ => nextcloud-talk-recording}/setup.py (100%) rename recording/packaging/{ => nextcloud-talk-recording}/stdeb.cfg (100%) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 3729f9075df..5bb021e8a5e 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -52,10 +52,7 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # - stdeb.cfg: additional configuration for stdeb (not needed in the # regenerated Python package, as stdeb loads it before changing to the # uncompressed source Python package). - cp --recursive debian $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp MANIFEST.in $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp setup.py $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - cp stdeb.cfg $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp --recursive nextcloud-talk-recording/. $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ # Build a source Debian package and then, from it, a binary Debian package # Since the 60.0.0 release, Setuptools includes a local, vendored copy of diff --git a/recording/packaging/MANIFEST.in b/recording/packaging/nextcloud-talk-recording/MANIFEST.in similarity index 100% rename from recording/packaging/MANIFEST.in rename to recording/packaging/nextcloud-talk-recording/MANIFEST.in diff --git a/recording/packaging/debian/py3dist-overrides b/recording/packaging/nextcloud-talk-recording/debian/py3dist-overrides similarity index 100% rename from recording/packaging/debian/py3dist-overrides rename to recording/packaging/nextcloud-talk-recording/debian/py3dist-overrides diff --git a/recording/packaging/setup.py b/recording/packaging/nextcloud-talk-recording/setup.py similarity index 100% rename from recording/packaging/setup.py rename to recording/packaging/nextcloud-talk-recording/setup.py diff --git a/recording/packaging/stdeb.cfg b/recording/packaging/nextcloud-talk-recording/stdeb.cfg similarity index 100% rename from recording/packaging/stdeb.cfg rename to recording/packaging/nextcloud-talk-recording/stdeb.cfg From 78c057b8d535428c264c2ad6b2e6ff62f06aa5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 18:04:36 +0100 Subject: [PATCH 12/25] Extract generic functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 5bb021e8a5e..01bfbb50de2 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -25,6 +25,17 @@ BUILD_DIR ?= build/$(OS_VERSION) NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") +build-source-python-package = python3 -m build --sdist --outdir $(1) $(2) + +extract-source-python-package = cd $(BUILD_DIR) && tar --extract --gzip --file $(1)-$(2).tar.gz + +# Since the 60.0.0 release, Setuptools includes a local, vendored copy of +# distutils; this copy does not seem to work with stdeb, so it needs to be +# disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". +build-deb-package = cd $(BUILD_DIR)/$(1)-$(2)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --debian-version $(DEBIAN_VERSION) bdist_deb + +copy-binary-deb-package = cp $(BUILD_DIR)/$(1)-$(2)/deb_dist/$(3)_$(2)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/ + $(BUILD_DIR)/deb: mkdir --parents $(BUILD_DIR)/deb @@ -32,11 +43,9 @@ build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb python3 -m pip install "setuptools >= 61.0" - # Build a source Python package - python3 -m build --sdist --outdir $(BUILD_DIR) ../ + $(call build-source-python-package,$(BUILD_DIR),../) - # Extract source Python package - cd $(BUILD_DIR) && tar --extract --gzip --file nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION).tar.gz + $(call extract-source-python-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) # Add extra files needed to create Debian packages: # - debian/py3dist-overrides: Python dependencies to Debian dependencies for @@ -54,11 +63,6 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # uncompressed source Python package). cp --recursive nextcloud-talk-recording/. $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - # Build a source Debian package and then, from it, a binary Debian package - # Since the 60.0.0 release, Setuptools includes a local, vendored copy of - # distutils; this copy does not seem to work with stdeb, so it needs to be - # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". - cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --debian-version $(DEBIAN_VERSION) bdist_deb + $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) - # Copy package to main build directory - cp $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/deb_dist/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/ + $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),python3-nextcloud-talk-recording) From 88a6a4302278a77cb1fbfe7637129b336b3b7c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 18:15:24 +0100 Subject: [PATCH 13/25] Do not explicitly install setuptools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than explicitly installing setuptools >= 61.0 from now on it is assumed to be a build dependency fulfilled before starting the build. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 01bfbb50de2..1ebb530eb82 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -41,8 +41,6 @@ $(BUILD_DIR)/deb: build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb - python3 -m pip install "setuptools >= 61.0" - $(call build-source-python-package,$(BUILD_DIR),../) $(call extract-source-python-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) From e27d17629f86aee92043ef96d9634efe040a1d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 18:31:19 +0100 Subject: [PATCH 14/25] Build Python dependencies not available in repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some Python packages are not available in the Ubuntu repositories, so now the missing packages are also built along with the recording server package. Some dependencies, like Selenium, also have unmet dependencies, so they are built as well. The built versions are not the minimum required versions but the latest versions that could be easily built. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 93 ++++++++++++++++++- recording/packaging/selenium/MANIFEST.in | 3 + .../selenium/debian/py3dist-overrides | 4 + 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 recording/packaging/selenium/MANIFEST.in create mode 100644 recording/packaging/selenium/debian/py3dist-overrides diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 1ebb530eb82..92e5c1a3414 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -25,8 +25,20 @@ BUILD_DIR ?= build/$(OS_VERSION) NEXTCLOUD_TALK_RECORDING_VERSION := $(shell cd ../src && python3 -c "from nextcloud.talk.recording import __version__; print(__version__)") +PULSECTL_VERSION := 22.3.2 +PYVIRTUALDISPLAY_VERSION := 3.0 +REQUESTS_VERSION := 2.25.0 +SELENIUM_VERSION := 4.8.2 + +CERTIFI_VERSION := 2022.12.7 +TRIO_VERSION := 0.21.0 +TRIO_WEBSOCKET_VERSION := 0.9.2 +URLLIB3_VERSION := 1.26.14 + build-source-python-package = python3 -m build --sdist --outdir $(1) $(2) +download-source-python-package = python3 -m pip download --dest $(BUILD_DIR) --no-binary :all: --no-deps "$(1) == $(2)" + extract-source-python-package = cd $(BUILD_DIR) && tar --extract --gzip --file $(1)-$(2).tar.gz # Since the 60.0.0 release, Setuptools includes a local, vendored copy of @@ -36,10 +48,19 @@ build-deb-package = cd $(BUILD_DIR)/$(1)-$(2)/ && SETUPTOOLS_USE_DISTUTILS=stdli copy-binary-deb-package = cp $(BUILD_DIR)/$(1)-$(2)/deb_dist/$(3)_$(2)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/ +define build-deb-python-package-full +$(call download-source-python-package,$(1),$(2)) +$(call extract-source-python-package,$(1),$(2)) +$(call build-deb-package,$(1),$(2)) +$(call copy-binary-deb-package,$(1),$(2),python3-$(3)) +endef + +build-packages-deb: build-packages-deb-nextcloud-talk-recording build-packages-deb-nextcloud-talk-recording-dependencies + $(BUILD_DIR)/deb: mkdir --parents $(BUILD_DIR)/deb -build-package-deb: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb +build-packages-deb-nextcloud-talk-recording: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb $(call build-source-python-package,$(BUILD_DIR),../) @@ -64,3 +85,73 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),python3-nextcloud-talk-recording) + +# Builds the Python dependencies that are not included in at least one of the +# Ubuntu supported releases: +# - Ubuntu 20.04 (focal): pulsectl, pyvirtualdisplay >= 2.0, requests >= 2.25, selenium >= 4.6.0 +# - Ubuntu 22.04 (jammy): pulsectl, selenium >= 4.6.0 +# +# requests is not an explicit dependency, but required by requests-toolbelt. +# However, requests < 2.25 is not compatible with urllib3 >= 1.26, which is +# required by selenium. +build-packages-deb-nextcloud-talk-recording-dependencies: build-packages-deb-nextcloud-talk-recording-dependencies-$(OS_VERSION) + +build-packages-deb-nextcloud-talk-recording-dependencies-ubuntu20.04: build-packages-deb-pulsectl build-packages-deb-pyvirtualdisplay build-packages-deb-requests build-packages-deb-selenium build-packages-deb-selenium-dependencies +build-packages-deb-nextcloud-talk-recording-dependencies-ubuntu22.04: build-packages-deb-pulsectl build-packages-deb-selenium build-packages-deb-selenium-dependencies + +build-packages-deb-pulsectl: $(BUILD_DIR)/deb/python3-pulsectl_$(PULSECTL_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-pulsectl_$(PULSECTL_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,pulsectl,$(PULSECTL_VERSION),pulsectl) + +build-packages-deb-pyvirtualdisplay: $(BUILD_DIR)/deb/python3-pyvirtualdisplay_$(PYVIRTUALDISPLAY_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-pyvirtualdisplay_$(PYVIRTUALDISPLAY_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,PyVirtualDisplay,$(PYVIRTUALDISPLAY_VERSION),pyvirtualdisplay) + +build-packages-deb-requests: $(BUILD_DIR)/deb/python3-requests_$(REQUESTS_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-requests_$(REQUESTS_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,requests,$(REQUESTS_VERSION),requests) + +build-packages-deb-selenium: $(BUILD_DIR)/deb/python3-selenium_$(SELENIUM_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-selenium_$(SELENIUM_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call download-source-python-package,selenium,$(SELENIUM_VERSION)) + + $(call extract-source-python-package,selenium,$(SELENIUM_VERSION)) + + # The Python dependencies are added automatically to the .deb dependencies, + # but they do not include the version. The supported distributions provide + # an incompatible version for some of the dependencies, so + # "debian/py3dist-overrides" is used to explicitly set the version in the + # .deb packages and ensure that the right dependency is installed. + cp --recursive selenium/debian $(BUILD_DIR)/selenium-$(SELENIUM_VERSION)/ + # The package provides its own MANIFEST.in, so the contents need to be + # appended rather than just copied. + cat selenium/MANIFEST.in >> $(BUILD_DIR)/selenium-$(SELENIUM_VERSION)/MANIFEST.in + + $(call build-deb-package,selenium,$(SELENIUM_VERSION)) + + $(call copy-binary-deb-package,selenium,$(SELENIUM_VERSION),python3-selenium) + +# Builds the Python dependencies that are not included in at least one of the +# Ubuntu supported releases: +# - Ubuntu 20.04 (focal): python3-certifi >= 2021.10.8, python3-trio ~= 0.17, python3-trio-websocket ~= 0.9, python3-urllib3 ~= 1.26 +# - Ubuntu 22.04 (jammy): python3-certifi >= 2021.10.8, python3-trio-websocket ~= 0.9 +build-packages-deb-selenium-dependencies: build-packages-deb-selenium-dependencies-$(OS_VERSION) + +build-packages-deb-selenium-dependencies-ubuntu20.04: build-packages-deb-certifi build-packages-deb-trio build-packages-deb-trio-websocket build-packages-deb-urllib +build-packages-deb-selenium-dependencies-ubuntu22.04: build-packages-deb-certifi build-packages-deb-trio-websocket + +build-packages-deb-certifi: $(BUILD_DIR)/deb/python3-certifi_$(CERTIFI_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-certifi_$(CERTIFI_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,certifi,$(CERTIFI_VERSION),certifi) + +build-packages-deb-trio: $(BUILD_DIR)/deb/python3-trio_$(TRIO_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-trio_$(TRIO_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,trio,$(TRIO_VERSION),trio) + +build-packages-deb-trio-websocket: $(BUILD_DIR)/deb/python3-trio-websocket_$(TRIO_WEBSOCKET_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-trio-websocket_$(TRIO_WEBSOCKET_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,trio-websocket,$(TRIO_WEBSOCKET_VERSION),trio-websocket) + +build-packages-deb-urllib: $(BUILD_DIR)/deb/python3-urllib3_$(URLLIB3_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/python3-urllib3_$(URLLIB3_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb + $(call build-deb-python-package-full,urllib3,$(URLLIB3_VERSION),urllib3) diff --git a/recording/packaging/selenium/MANIFEST.in b/recording/packaging/selenium/MANIFEST.in new file mode 100644 index 00000000000..6785a66336a --- /dev/null +++ b/recording/packaging/selenium/MANIFEST.in @@ -0,0 +1,3 @@ +graft debian +include selenium/types.py +include selenium/webdriver/common/linux/selenium-manager diff --git a/recording/packaging/selenium/debian/py3dist-overrides b/recording/packaging/selenium/debian/py3dist-overrides new file mode 100644 index 00000000000..2aa96e4ae78 --- /dev/null +++ b/recording/packaging/selenium/debian/py3dist-overrides @@ -0,0 +1,4 @@ +urllib3 python3-urllib3 (>=1.26), python3-urllib3 (<<2.0) +trio python3-trio (>=0.17), python3-trio (<<1.0) +trio-websocket python3-trio-websocket (>=0.9), python3-trio-websocket (<<1.0) +certifi python3-certifi (>=2021.10.8) From 178d848024ee6599a613f29deadf8817043a6bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 22:01:41 +0100 Subject: [PATCH 15/25] Make builds reproducible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stdeb supports setting SOURCE_DATE_EPOCH to have reproducible builds, so it is now set to the git timestamp of the recording directory for the recording server and the date of the root directory in the source Python package for the dependencies. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 92e5c1a3414..33aa38d70ed 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -35,6 +35,10 @@ TRIO_VERSION := 0.21.0 TRIO_WEBSOCKET_VERSION := 0.9.2 URLLIB3_VERSION := 1.26.14 +timestamp-from-git = git log -1 --pretty=%ct $(1) + +timestamp-from-source-python-package = tar --list --verbose --full-time --gzip --file $(1) | head --lines 1 | sed 's/ \+/ /g' | cut --delimiter " " --fields 4-5 | date --file - +%s + build-source-python-package = python3 -m build --sdist --outdir $(1) $(2) download-source-python-package = python3 -m pip download --dest $(BUILD_DIR) --no-binary :all: --no-deps "$(1) == $(2)" @@ -44,14 +48,14 @@ extract-source-python-package = cd $(BUILD_DIR) && tar --extract --gzip --file $ # Since the 60.0.0 release, Setuptools includes a local, vendored copy of # distutils; this copy does not seem to work with stdeb, so it needs to be # disabled with "SETUPTOOLS_USE_DISTUTILS=stdlib". -build-deb-package = cd $(BUILD_DIR)/$(1)-$(2)/ && SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --debian-version $(DEBIAN_VERSION) bdist_deb +build-deb-package = cd $(BUILD_DIR)/$(1)-$(2)/ && SOURCE_DATE_EPOCH=$(3) SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --debian-version $(DEBIAN_VERSION) bdist_deb copy-binary-deb-package = cp $(BUILD_DIR)/$(1)-$(2)/deb_dist/$(3)_$(2)-$(DEBIAN_VERSION)_all.deb $(BUILD_DIR)/deb/ define build-deb-python-package-full $(call download-source-python-package,$(1),$(2)) $(call extract-source-python-package,$(1),$(2)) -$(call build-deb-package,$(1),$(2)) +$(call build-deb-package,$(1),$(2),$$($(call timestamp-from-source-python-package,../$(1)-$(2).tar.gz))) $(call copy-binary-deb-package,$(1),$(2),python3-$(3)) endef @@ -82,7 +86,7 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # uncompressed source Python package). cp --recursive nextcloud-talk-recording/. $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) + $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),$$($(call timestamp-from-git,../../../../))) $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),python3-nextcloud-talk-recording) @@ -127,7 +131,7 @@ $(BUILD_DIR)/deb/python3-selenium_$(SELENIUM_VERSION)-$(DEBIAN_VERSION)_all.deb: # appended rather than just copied. cat selenium/MANIFEST.in >> $(BUILD_DIR)/selenium-$(SELENIUM_VERSION)/MANIFEST.in - $(call build-deb-package,selenium,$(SELENIUM_VERSION)) + $(call build-deb-package,selenium,$(SELENIUM_VERSION),$$($(call timestamp-from-source-python-package,../selenium-$(SELENIUM_VERSION).tar.gz))) $(call copy-binary-deb-package,selenium,$(SELENIUM_VERSION),python3-selenium) From cc27cf450806191392633ebcd779e176d74fd18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 14 Mar 2023 22:40:14 +0100 Subject: [PATCH 16/25] Add example configuration in the recording server package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Installed files can not be renamed with the standard ".install" syntax; "dh-exec" needs to be used instead. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 1 + recording/packaging/nextcloud-talk-recording/MANIFEST.in | 1 + .../debian/python3-nextcloud-talk-recording.install | 2 ++ recording/packaging/nextcloud-talk-recording/stdeb.cfg | 1 + 4 files changed, 5 insertions(+) create mode 100755 recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 33aa38d70ed..900ea399c46 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -85,6 +85,7 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # regenerated Python package, as stdeb loads it before changing to the # uncompressed source Python package). cp --recursive nextcloud-talk-recording/. $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ + cp ../server.conf.in $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),$$($(call timestamp-from-git,../../../../))) diff --git a/recording/packaging/nextcloud-talk-recording/MANIFEST.in b/recording/packaging/nextcloud-talk-recording/MANIFEST.in index b3009faaf41..5b877935a0e 100644 --- a/recording/packaging/nextcloud-talk-recording/MANIFEST.in +++ b/recording/packaging/nextcloud-talk-recording/MANIFEST.in @@ -1 +1,2 @@ graft debian +include server.conf.in diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install new file mode 100755 index 00000000000..3188cb098fd --- /dev/null +++ b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +server.conf.in => /etc/nextcloud-talk-recording/server.conf diff --git a/recording/packaging/nextcloud-talk-recording/stdeb.cfg b/recording/packaging/nextcloud-talk-recording/stdeb.cfg index 36bb6c18b8e..1c1bd9290c4 100644 --- a/recording/packaging/nextcloud-talk-recording/stdeb.cfg +++ b/recording/packaging/nextcloud-talk-recording/stdeb.cfg @@ -1,2 +1,3 @@ [DEFAULT] +Build-Depends: dh-exec Depends3: ffmpeg, firefox, firefox-geckodriver, pulseaudio, xvfb From ff34f670fecfef62db2696e98139590677bbfad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 15 Mar 2023 00:33:51 +0100 Subject: [PATCH 17/25] Add executable for the recording server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than having to call "python3" and specify the module an executable to be called just as "nextcloud-talk-recording" was added for convenience. However, right now it is not possible to just specify a module to be loaded; as a function is needed to entry module is now wrapped in a function that is explicitly called for the executable and implicitly called when the module is loaded, thus keeping the previous behaviour. Signed-off-by: Daniel Calviño Sánchez --- recording/pyproject.toml | 3 +++ .../src/nextcloud/talk/recording/__main__.py | 22 +++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/recording/pyproject.toml b/recording/pyproject.toml index 7835f57996a..baa8c3978f7 100644 --- a/recording/pyproject.toml +++ b/recording/pyproject.toml @@ -21,5 +21,8 @@ dynamic = ["version"] [project.urls] repository = "https://github.com/nextcloud/spreed" +[project.scripts] +nextcloud-talk-recording = "nextcloud.talk.recording.__main__:main" + [tool.setuptools.dynamic] version = {attr = "nextcloud.talk.recording.__version__"} diff --git a/recording/src/nextcloud/talk/recording/__main__.py b/recording/src/nextcloud/talk/recording/__main__.py index e86806f5483..6ebc67cc86d 100644 --- a/recording/src/nextcloud/talk/recording/__main__.py +++ b/recording/src/nextcloud/talk/recording/__main__.py @@ -23,16 +23,20 @@ from .Config import config from .Server import app -parser = argparse.ArgumentParser() -parser.add_argument("-c", "--config", help="path to configuration file", default="server.conf") -args = parser.parse_args() +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--config", help="path to configuration file", default="server.conf") + args = parser.parse_args() -config.load(args.config) + config.load(args.config) -logging.basicConfig(level=config.getLogLevel()) -logging.getLogger('werkzeug').setLevel(config.getLogLevel()) + logging.basicConfig(level=config.getLogLevel()) + logging.getLogger('werkzeug').setLevel(config.getLogLevel()) -listen = config.getListen() -host, port = listen.split(':') + listen = config.getListen() + host, port = listen.split(':') -app.run(host, port, threaded=True) + app.run(host, port, threaded=True) + +if __name__ == '__main__': + main() From 3ed6f23673706777d7c8606c743f847c4705fa94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 15 Mar 2023 11:49:47 +0100 Subject: [PATCH 18/25] Add option to just show the version and exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/src/nextcloud/talk/recording/__main__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/recording/src/nextcloud/talk/recording/__main__.py b/recording/src/nextcloud/talk/recording/__main__.py index 6ebc67cc86d..bdad62e69c9 100644 --- a/recording/src/nextcloud/talk/recording/__main__.py +++ b/recording/src/nextcloud/talk/recording/__main__.py @@ -20,14 +20,21 @@ import argparse import logging +from nextcloud.talk import recording from .Config import config from .Server import app def main(): parser = argparse.ArgumentParser() parser.add_argument("-c", "--config", help="path to configuration file", default="server.conf") + parser.add_argument("-v", "--version", help="show version and quit", action="store_true") args = parser.parse_args() + if args.version: + print(recording.__version__) + + return + config.load(args.config) logging.basicConfig(level=config.getLogLevel()) From dc3b01519fb08b2329c4eea55986ac4e3d10c3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 15 Mar 2023 11:54:52 +0100 Subject: [PATCH 19/25] Add systemd service for the recording server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recording server does not need to be run as root, although it needs a home directory to store some Firefox and Pulseaudio related files (not explicitly created by the recording server but by the services themselves). Therefore a system user, which can not log in, but with a home directory, is used to run it. The systemd addon for dh is used when creating the package, so "dh_systemd_enable" and "dh_systemd_start" will be automatically called when building the package. Those helpers will take care of enabling and starting the service as needed when the package is installed. Nevertheless, as a custom ".postint" script is used "#DEBHELPER#" needs to be explicitly called to add the code of the helpers. Unfortunately the service is named "python3-nextcloud-talk-recording", just like the package, as renaming the service requires a "debian/rules" file with a content like: override_dh_installsystemd: dh_installsystemd --name=nextcloud-talk-recording but stdeb provides its own "debian/rules" files and there does not seem to be a way to extend/customize it. Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 4 +++- .../debian/python3-nextcloud-talk-recording.postinst | 10 ++++++++++ .../debian/python3-nextcloud-talk-recording.service | 12 ++++++++++++ .../packaging/nextcloud-talk-recording/stdeb.cfg | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst create mode 100644 recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 900ea399c46..b18b4e80f1a 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -87,7 +87,9 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER cp --recursive nextcloud-talk-recording/. $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ cp ../server.conf.in $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ - $(call build-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),$$($(call timestamp-from-git,../../../../))) + # Build a source Debian package (with the systemd addon for dh) and then, + # from it, a binary Debian package. + cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SOURCE_DATE_EPOCH=$$($(call timestamp-from-git,../../../../)) SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --with-dh-systemd --debian-version $(DEBIAN_VERSION) bdist_deb $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),python3-nextcloud-talk-recording) diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst new file mode 100644 index 00000000000..3989d6b46c4 --- /dev/null +++ b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +# The user running nextcloud-talk-recording needs a home directory for +# geckodriver and PulseAudio related files. +# The user will not be automatically removed if the package is uninstalled or +# purged to avoid leaving behind files owned by the user/group. +adduser --system nextcloud-talk-recording + +#DEBHELPER# diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service new file mode 100644 index 00000000000..0e13dc7f1b4 --- /dev/null +++ b/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service @@ -0,0 +1,12 @@ +[Unit] +Description=Recording server for Nextcloud Talk +After=network.target + +[Service] +User=nextcloud-talk-recording +WorkingDirectory=~ +ExecStart=/usr/bin/nextcloud-talk-recording --config /etc/nextcloud-talk-recording/server.conf +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/recording/packaging/nextcloud-talk-recording/stdeb.cfg b/recording/packaging/nextcloud-talk-recording/stdeb.cfg index 1c1bd9290c4..608d207f120 100644 --- a/recording/packaging/nextcloud-talk-recording/stdeb.cfg +++ b/recording/packaging/nextcloud-talk-recording/stdeb.cfg @@ -1,3 +1,3 @@ [DEFAULT] Build-Depends: dh-exec -Depends3: ffmpeg, firefox, firefox-geckodriver, pulseaudio, xvfb +Depends3: adduser, ffmpeg, firefox, firefox-geckodriver, pulseaudio, xvfb From 22e039455ccdd67f5495c48dda4d93cd0c55cdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 15 Mar 2023 14:57:52 +0100 Subject: [PATCH 20/25] Add helper script to build the packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script creates one container for each supported distribution, installs the needed dependencies and then builds the packages. The recording server directory is mounted in the containers so the packages can be built in the "build" subdirectory of the actual recording server directory. In the containers the building is done as the owner of the recording server directory, so the built files are also owned by that user. For simplicity, and given that the containers are not expected to be used for anything else, the volume with the recording server is mounted as a direct child of the root directory (forgive me FSH for I have sinned). Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/build.sh | 191 +++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 recording/packaging/build.sh diff --git a/recording/packaging/build.sh b/recording/packaging/build.sh new file mode 100755 index 00000000000..3eeea1f04f6 --- /dev/null +++ b/recording/packaging/build.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash + +# @copyright Copyright (c) 2023, Daniel Calviño Sánchez (danxuliu@gmail.com) +# +# @license GNU AGPL version 3 or any later version +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# Helper script to build the recording backend packages for Nextcloud Talk. +# +# This script creates containers with the supported operating systems, installs +# all the needed dependencies in them and builds the packages for the recording +# backend inside the container. If the container exists already the previous +# container will be reused and this script will simply build the recording +# backend in it. The packages will be created in the +# "build/{DISTRIBUTION-ID}/{PACKAGE-FORMAT}/" directory under "packaging" with +# the same user that owns the "packaging" directory. +# +# Due to that the Docker container will not be stopped nor removed when the +# script exits (except when the container was created but it could not be +# started); that must be explicitly done once the container is no longer needed. +# +# +# +# DOCKER AND PERMISSIONS +# +# To perform its job, this script requires the "docker" command to be available. +# +# The Docker Command Line Interface (the "docker" command) requires special +# permissions to talk to the Docker daemon, and those permissions are typically +# available only to the root user. Please see the Docker documentation to find +# out how to give access to a regular user to the Docker daemon: +# https://docs.docker.com/engine/installation/linux/linux-postinstall/ +# +# Note, however, that being able to communicate with the Docker daemon is the +# same as being able to get root privileges for the system. Therefore, you must +# give access to the Docker daemon (and thus run this script as) ONLY to trusted +# and secure users: +# https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface + +# Sets the variables that abstract the differences in command names and options +# between operating systems. +# +# Switches between timeout on GNU/Linux and gtimeout on macOS (same for mktemp +# and gmktemp). +function setOperatingSystemAbstractionVariables() { + case "$OSTYPE" in + darwin*) + if [ "$(which gtimeout)" == "" ]; then + echo "Please install coreutils (brew install coreutils)" + exit 1 + fi + + MKTEMP=gmktemp + TIMEOUT=gtimeout + DOCKER_OPTIONS="-e no_proxy=localhost " + ;; + linux*) + MKTEMP=mktemp + TIMEOUT=timeout + DOCKER_OPTIONS=" " + ;; + *) + echo "Operating system ($OSTYPE) not supported" + exit 1 + ;; + esac +} + +# Removes Docker container if it was created but failed to start. +function cleanUp() { + # Disable (yes, "+" disables) exiting immediately on errors to ensure that + # all the cleanup commands are executed (well, no errors should occur during + # the cleanup anyway, but just in case). + set +o errexit + + # The name filter must be specified as "^/XXX$" to get an exact match; using + # just "XXX" would match every name that contained "XXX". + if [ -n "$(docker ps --all --quiet --filter status=created --filter name="^/$CONTAINER-ubuntu20.04$")" ]; then + echo "Removing Docker container $CONTAINER-ubuntu20.04" + docker rm --volumes --force $CONTAINER-ubuntu20.04 + fi + if [ -n "$(docker ps --all --quiet --filter status=created --filter name="^/$CONTAINER-ubuntu22.04$")" ]; then + echo "Removing Docker container $CONTAINER-ubuntu22.04" + docker rm --volumes --force $CONTAINER-ubuntu22.04 + fi +} + +# Exit immediately on errors. +set -o errexit + +# Execute cleanUp when the script exits, either normally or due to an error. +trap cleanUp EXIT + +# Ensure working directory is script directory, as some actions (like mounting +# the volumes in the container) expect that. +cd "$(dirname $0)" + +HELP="Usage: $(basename $0) [OPTION]... + +Options (all options can be omitted, but when present they must appear in the +following order): +--help prints this help and exits. +--container CONTAINER_NAME the name (prefix) to assign to the containers. + Defaults to nextcloud-talk-recording-packages-builder." +if [ "$1" = "--help" ]; then + echo "$HELP" + + exit 0 +fi + +CONTAINER="nextcloud-talk-recording-packages-builder" +if [ "$1" = "--container" ]; then + CONTAINER="$2" + + shift 2 +fi + +if [ -n "$1" ]; then + echo "Invalid option (or at invalid position): $1 + +$HELP" + + exit 1 +fi + +setOperatingSystemAbstractionVariables + +# If the containers are not found new ones are prepared. Otherwise the existing +# containers are used. +# +# The name filter must be specified as "^/XXX$" to get an exact match; using +# just "XXX" would match every name that contained "XXX". +if [ -z "$(docker ps --all --quiet --filter name="^/$CONTAINER-ubuntu20.04$")" ]; then + echo "Creating Nextcloud Talk recording packages builder container for Ubuntu 20.04" + # The main Talk directory is mounted rather than just the recording + # directory to be able to get the timestamp from git for reproducible + # builds. + docker run --detach --tty --volume "$(realpath ../../)":/spreed/ --name=$CONTAINER-ubuntu20.04 $DOCKER_OPTIONS ubuntu:20.04 bash + + echo "Installing required build dependencies" + # "noninteractive" is used to provide default settings instead of asking for + # them (for example, for tzdata). + docker exec $CONTAINER-ubuntu20.04 bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes make python3 python3-pip python3-venv python3-all debhelper dh-python git dh-exec" + docker exec $CONTAINER-ubuntu20.04 bash -c "python3 -m pip install stdeb build 'setuptools >= 61.0'" +fi +if [ -z "$(docker ps --all --quiet --filter name="^/$CONTAINER-ubuntu22.04$")" ]; then + echo "Creating Nextcloud Talk recording packages builder container for Ubuntu 22.04" + # The main Talk directory is mounted rather than just the recording + # directory to be able to get the timestamp from git for reproducible + # builds. + docker run --detach --tty --volume "$(realpath ../../)":/spreed/ --name=$CONTAINER-ubuntu22.04 $DOCKER_OPTIONS ubuntu:22.04 bash + + echo "Installing required build dependencies" + # "noninteractive" is used to provide default settings instead of asking for + # them (for example, for tzdata). + docker exec $CONTAINER-ubuntu22.04 bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes make python3 python3-pip python3-virtualenv python3-build python3-stdeb python3-all debhelper dh-python git dh-exec" + docker exec $CONTAINER-ubuntu22.04 bash -c "python3 -m pip install 'setuptools >= 61.0'" + # Some packages need to be installed so the unit tests can be run in the + # packages being built. + docker exec $CONTAINER-ubuntu22.04 bash -c "apt-get install --assume-yes pulseaudio python3-async-generator python3-trio python3-wsproto" +fi + +# Start existing containers if they are stopped. +if [ -n "$(docker ps --all --quiet --filter status=exited --filter name="^/$CONTAINER-ubuntu20.04$")" ]; then + echo "Starting Talk recording packages builder container for Ubuntu 20.04" + docker start $CONTAINER-ubuntu20.04 +fi +if [ -n "$(docker ps --all --quiet --filter status=exited --filter name="^/$CONTAINER-ubuntu22.04$")" ]; then + echo "Starting Talk recording packages builder container for Ubuntu 22.04" + docker start $CONTAINER-ubuntu22.04 +fi + +USER=$(ls -l --numeric-uid-gid --directory . | sed 's/ \+/ /g' | cut --delimiter " " --fields 3) + +echo "Building recording backend packages for Ubuntu 20.04" +docker exec --tty --interactive --user $USER --workdir /spreed/recording/packaging $CONTAINER-ubuntu20.04 make + +echo "Building recording backend packages for Ubuntu 22.04" +docker exec --tty --interactive --user $USER --workdir /spreed/recording/packaging $CONTAINER-ubuntu22.04 make From 79b4e595497df8fc45eb094dee91f6a29901de5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 11 Sep 2023 12:26:40 +0200 Subject: [PATCH 21/25] Add dependency and executable for the benchmark tool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The benchmark tool has a specific dependency (psutil) that is not required for the rest of the recording server. However, for simplicity, rather than splitting the benchmark in its own Python project and package its dependency and helper script is now included in the main project and package (the code was already there). Signed-off-by: Daniel Calviño Sánchez --- recording/docs/encoders.md | 4 ++-- recording/pyproject.toml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/recording/docs/encoders.md b/recording/docs/encoders.md index 1fa72635f82..72dfaa95c66 100644 --- a/recording/docs/encoders.md +++ b/recording/docs/encoders.md @@ -16,7 +16,7 @@ The benchmark tool does not record an actual call; it plays a video file and rec ### Usage example -The different options accepted by the benchmark tool can be seen with `python3 -m nextcloud.talk.recording.Benchmark --help`. +The different options accepted by the benchmark tool can be seen with `nextcloud-talk-recording-benchmark --help` (or, if the helper script is not available, directly with `python3 -m nextcloud.talk.recording.Benchmark --help`). Each run of the benchmark tool records a single video (or audio) file with the given options. Using a Bash script several runs can be batched to check the result of running different options. For example: ``` @@ -51,6 +51,6 @@ do # Split the input tuple on "," IFS="," read FFMPEG_OUTPUT_VIDEO FILENAME_SUFFIX <<< "${TEST}" # Run the test - python3 -m nextcloud.talk.recording.Benchmark --length 300 --ffmpeg-output-video "${FFMPEG_OUTPUT_VIDEO}" /tmp/recording/files/example.mkv /tmp/recording/files/test-"${FILENAME_SUFFIX}".webm + nextcloud-talk-recording-benchmark --length 300 --ffmpeg-output-video "${FFMPEG_OUTPUT_VIDEO}" /tmp/recording/files/example.mkv /tmp/recording/files/test-"${FILENAME_SUFFIX}".webm done ``` diff --git a/recording/pyproject.toml b/recording/pyproject.toml index baa8c3978f7..79614c57a3a 100644 --- a/recording/pyproject.toml +++ b/recording/pyproject.toml @@ -10,6 +10,7 @@ classifiers = [ ] dependencies = [ "flask", + "psutil", "pulsectl", "pyvirtualdisplay>=2.0", "requests-toolbelt", @@ -23,6 +24,7 @@ repository = "https://github.com/nextcloud/spreed" [project.scripts] nextcloud-talk-recording = "nextcloud.talk.recording.__main__:main" +nextcloud-talk-recording-benchmark = "nextcloud.talk.recording.Benchmark:main" [tool.setuptools.dynamic] version = {attr = "nextcloud.talk.recording.__version__"} From f1528c844d89f6c7b6d6f5b4473b3dd24bdb89da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 20 Sep 2023 11:37:53 +0200 Subject: [PATCH 22/25] Rename package to "nextcloud-talk-recording" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default stdeb prefixes the package name with "python3-". However, even if other Python modules could import the Python code of the recording server it is not designed as a library, it is an executable that happens to be written in Python, so to speak. Moreover, besides the Python code itself the package also includes a configuration file and a systemd service, which do not belong to "python3-" packages (there are also helper executable scripts, although those are allowed in "python3-" packages). Due to all that the package "python3-nextcloud-talk-recording" is now renamed to "nextcloud-talk-recording". Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 6 +++--- ...k-recording.install => nextcloud-talk-recording.install} | 0 ...recording.postinst => nextcloud-talk-recording.postinst} | 0 ...k-recording.service => nextcloud-talk-recording.service} | 0 recording/packaging/nextcloud-talk-recording/stdeb.cfg | 1 + 5 files changed, 4 insertions(+), 3 deletions(-) rename recording/packaging/nextcloud-talk-recording/debian/{python3-nextcloud-talk-recording.install => nextcloud-talk-recording.install} (100%) rename recording/packaging/nextcloud-talk-recording/debian/{python3-nextcloud-talk-recording.postinst => nextcloud-talk-recording.postinst} (100%) rename recording/packaging/nextcloud-talk-recording/debian/{python3-nextcloud-talk-recording.service => nextcloud-talk-recording.service} (100%) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index b18b4e80f1a..6dadb4323b6 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -64,8 +64,8 @@ build-packages-deb: build-packages-deb-nextcloud-talk-recording build-packages-d $(BUILD_DIR)/deb: mkdir --parents $(BUILD_DIR)/deb -build-packages-deb-nextcloud-talk-recording: $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb -$(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb +build-packages-deb-nextcloud-talk-recording: $(BUILD_DIR)/deb/nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb +$(BUILD_DIR)/deb/nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$(DEBIAN_VERSION)_all.deb: | $(BUILD_DIR)/deb $(call build-source-python-package,$(BUILD_DIR),../) $(call extract-source-python-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION)) @@ -91,7 +91,7 @@ $(BUILD_DIR)/deb/python3-nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VER # from it, a binary Debian package. cd $(BUILD_DIR)/nextcloud-talk-recording-$(NEXTCLOUD_TALK_RECORDING_VERSION)/ && SOURCE_DATE_EPOCH=$$($(call timestamp-from-git,../../../../)) SETUPTOOLS_USE_DISTUTILS=stdlib python3 setup.py --command-packages=stdeb.command sdist_dsc --with-dh-systemd --debian-version $(DEBIAN_VERSION) bdist_deb - $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),python3-nextcloud-talk-recording) + $(call copy-binary-deb-package,nextcloud-talk-recording,$(NEXTCLOUD_TALK_RECORDING_VERSION),nextcloud-talk-recording) # Builds the Python dependencies that are not included in at least one of the # Ubuntu supported releases: diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install b/recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.install similarity index 100% rename from recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.install rename to recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.install diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst b/recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.postinst similarity index 100% rename from recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.postinst rename to recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.postinst diff --git a/recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service b/recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.service similarity index 100% rename from recording/packaging/nextcloud-talk-recording/debian/python3-nextcloud-talk-recording.service rename to recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.service diff --git a/recording/packaging/nextcloud-talk-recording/stdeb.cfg b/recording/packaging/nextcloud-talk-recording/stdeb.cfg index 608d207f120..0aa118136f7 100644 --- a/recording/packaging/nextcloud-talk-recording/stdeb.cfg +++ b/recording/packaging/nextcloud-talk-recording/stdeb.cfg @@ -1,3 +1,4 @@ [DEFAULT] +Package3: nextcloud-talk-recording Build-Depends: dh-exec Depends3: adduser, ffmpeg, firefox, firefox-geckodriver, pulseaudio, xvfb From 2b27419c5db40e8520a2a727149deb57b7a427d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 20 Sep 2023 16:02:11 +0200 Subject: [PATCH 23/25] Add support for building packages in Debian 11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/packaging/Makefile | 4 ++++ recording/packaging/build.sh | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/recording/packaging/Makefile b/recording/packaging/Makefile index 6dadb4323b6..526184057cf 100644 --- a/recording/packaging/Makefile +++ b/recording/packaging/Makefile @@ -95,6 +95,7 @@ $(BUILD_DIR)/deb/nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$( # Builds the Python dependencies that are not included in at least one of the # Ubuntu supported releases: +# - Debian 11 (bullseye): pulsectl, pyvirtualdisplay >= 2.0, selenium >= 4.6.0 # - Ubuntu 20.04 (focal): pulsectl, pyvirtualdisplay >= 2.0, requests >= 2.25, selenium >= 4.6.0 # - Ubuntu 22.04 (jammy): pulsectl, selenium >= 4.6.0 # @@ -103,6 +104,7 @@ $(BUILD_DIR)/deb/nextcloud-talk-recording_$(NEXTCLOUD_TALK_RECORDING_VERSION)-$( # required by selenium. build-packages-deb-nextcloud-talk-recording-dependencies: build-packages-deb-nextcloud-talk-recording-dependencies-$(OS_VERSION) +build-packages-deb-nextcloud-talk-recording-dependencies-debian11: build-packages-deb-pulsectl build-packages-deb-pyvirtualdisplay build-packages-deb-selenium build-packages-deb-selenium-dependencies build-packages-deb-nextcloud-talk-recording-dependencies-ubuntu20.04: build-packages-deb-pulsectl build-packages-deb-pyvirtualdisplay build-packages-deb-requests build-packages-deb-selenium build-packages-deb-selenium-dependencies build-packages-deb-nextcloud-talk-recording-dependencies-ubuntu22.04: build-packages-deb-pulsectl build-packages-deb-selenium build-packages-deb-selenium-dependencies @@ -140,10 +142,12 @@ $(BUILD_DIR)/deb/python3-selenium_$(SELENIUM_VERSION)-$(DEBIAN_VERSION)_all.deb: # Builds the Python dependencies that are not included in at least one of the # Ubuntu supported releases: +# - Debian 11 (bullseye): python3-certifi >= 2021.10.8, python3-trio ~= 0.17, python3-trio-websocket ~= 0.9 # - Ubuntu 20.04 (focal): python3-certifi >= 2021.10.8, python3-trio ~= 0.17, python3-trio-websocket ~= 0.9, python3-urllib3 ~= 1.26 # - Ubuntu 22.04 (jammy): python3-certifi >= 2021.10.8, python3-trio-websocket ~= 0.9 build-packages-deb-selenium-dependencies: build-packages-deb-selenium-dependencies-$(OS_VERSION) +build-packages-deb-selenium-dependencies-debian11: build-packages-deb-certifi build-packages-deb-trio build-packages-deb-trio-websocket build-packages-deb-selenium-dependencies-ubuntu20.04: build-packages-deb-certifi build-packages-deb-trio build-packages-deb-trio-websocket build-packages-deb-urllib build-packages-deb-selenium-dependencies-ubuntu22.04: build-packages-deb-certifi build-packages-deb-trio-websocket diff --git a/recording/packaging/build.sh b/recording/packaging/build.sh index 3eeea1f04f6..5493133e00c 100755 --- a/recording/packaging/build.sh +++ b/recording/packaging/build.sh @@ -87,6 +87,10 @@ function cleanUp() { # The name filter must be specified as "^/XXX$" to get an exact match; using # just "XXX" would match every name that contained "XXX". + if [ -n "$(docker ps --all --quiet --filter status=created --filter name="^/$CONTAINER-debian11$")" ]; then + echo "Removing Docker container $CONTAINER-debian11" + docker rm --volumes --force $CONTAINER-debian11 + fi if [ -n "$(docker ps --all --quiet --filter status=created --filter name="^/$CONTAINER-ubuntu20.04$")" ]; then echo "Removing Docker container $CONTAINER-ubuntu20.04" docker rm --volumes --force $CONTAINER-ubuntu20.04 @@ -142,6 +146,19 @@ setOperatingSystemAbstractionVariables # # The name filter must be specified as "^/XXX$" to get an exact match; using # just "XXX" would match every name that contained "XXX". +if [ -z "$(docker ps --all --quiet --filter name="^/$CONTAINER-debian11$")" ]; then + echo "Creating Nextcloud Talk recording packages builder container for Debian 11" + # The main Talk directory is mounted rather than just the recording + # directory to be able to get the timestamp from git for reproducible + # builds. + docker run --detach --tty --volume "$(realpath ../../)":/spreed/ --name=$CONTAINER-debian11 $DOCKER_OPTIONS debian:11 bash + + echo "Installing required build dependencies" + # "noninteractive" is used to provide default settings instead of asking for + # them (for example, for tzdata). + docker exec $CONTAINER-debian11 bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes make python3 python3-pip python3-venv python3-all debhelper dh-python git dh-exec" + docker exec $CONTAINER-debian11 bash -c "python3 -m pip install stdeb build 'setuptools >= 61.0'" +fi if [ -z "$(docker ps --all --quiet --filter name="^/$CONTAINER-ubuntu20.04$")" ]; then echo "Creating Nextcloud Talk recording packages builder container for Ubuntu 20.04" # The main Talk directory is mounted rather than just the recording @@ -184,6 +201,9 @@ fi USER=$(ls -l --numeric-uid-gid --directory . | sed 's/ \+/ /g' | cut --delimiter " " --fields 3) +echo "Building recording backend packages for Debian 11" +docker exec --tty --interactive --user $USER --workdir /spreed/recording/packaging $CONTAINER-debian11 make + echo "Building recording backend packages for Ubuntu 20.04" docker exec --tty --interactive --user $USER --workdir /spreed/recording/packaging $CONTAINER-ubuntu20.04 make From 54a747a8a3dc7bd691c03bc9f530853269336575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 23 Mar 2023 15:34:33 +0100 Subject: [PATCH 24/25] Add documentation for installing the recording server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/docs/index.md | 6 +- recording/docs/installation.md | 241 +++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 recording/docs/installation.md diff --git a/recording/docs/index.md b/recording/docs/index.md index 351f5740131..eaabb9a1c86 100644 --- a/recording/docs/index.md +++ b/recording/docs/index.md @@ -1,6 +1,10 @@ # Nextcloud Talk Recording Server Documentation -## Configuration +## Setup + +* [Installation](installation.md) + +### Configuration * [Encoders](encoders.md) diff --git a/recording/docs/installation.md b/recording/docs/installation.md new file mode 100644 index 00000000000..316a4770c3f --- /dev/null +++ b/recording/docs/installation.md @@ -0,0 +1,241 @@ +# Installation + +The recording server requires an HPB (High Performance Backend for Talk) to be setup. However, it is recommended to setup the recording server in a different machine than the HPB to prevent their load to interfere with each other. Moreover, as the recording server requires some dependencies that are not typically found in server machines, like Firefox, it is recommended to use its own "isolated" machine (either a real machine or a virtual machine). A container would also work, although it might require a special configuration to start the server when the container is started. + +In practice the recording server acts just as another Talk client, so it could be located anywhere as long as it can connect to the Nextcloud server and to the HPB, in the later case either directly or through the TURN server. Nevertheless, for simplicity and reliability, it is recommended for the recording server to have direct access to the HPB (so if the HPB is running in an internal network the recording server should be setup in that same internal network as the HPB). + +## Hardware requirements + +As a quick reference, with the default settings, in an AMD Ryzen 7 3700X 8-Core Processor (so 16 threads, theoretically a maximum usage of 1600% CPU) recording a single call uses 200% CPU (mostly to encode the video). The recording server provides [a benchmark tool](encoders.md) that can be used to check the load with different encoding settings and find out an approximation of the load that will occur when recording a call. Nevertheless in a real recording there is an additional load from the WebRTC connections, the rendering of the browser and so on, but in general the encoding uses the most CPU. + +Regarding RAM memory the encoding does not use much, and it should be calculated based on how many simultaneous recordings and therefore browsers are expected. For a single browser 2 GiB should be enough, although it would be recommended to play safe and have more if possible due to the increasing memory requirements of browsers (and also if the calls to be recorded include a lot of participants). + +Finally disk size will also depend on the number of simultaneous recordings, as well as the quality and codec used, which directly affect the size of the recording. In general the recorded videos will stay on the recording server only while being recorded and they will be removed as soon as they are uploaded to the Nextcloud server. However, if the upload fails the recorded video will be kept in the recording server until manually removed. + +## Installation type + +The recording server can be installed using system packages in some GNU/Linux distributions. A "manual" installation is required for others. + +In both cases the master branch of the [Nextcloud Talk repository](https://github.com/nextcloud/spreed) should be cloned. Currently the recording server in the master branch is backwards compatible with previous Talk releases, and the stable branches do not receive bug fixes for the recording server, as the latest version from the master branch is expected to be used. + +### System packages + +Distribution packages are supported for the following GNU/Linux distributions: +- Debian 11 +- Ubuntu 20.04 +- Ubuntu 22.04 + +They can be built on those distributions by calling `make` in the _recording/packaging_ directory of the git sources. Nevertheless, the Makefile assumes that the build dependencies have been already installed in the system. Therefore it is recommended to run `build.sh` in the _recording/packaging_ directory, which will create Docker containers with the required dependencies and then run `make` inside them. Alternatively the dependencies can be checked under `Installing required build dependencies` in `build.sh` and manually installed in the system. Using `build.sh` the packages can be built for those target distributions on other distributions too. + +The built packages can be found in _recording/packaging/build/{DISTRIBUTION-ID}/{PACKAGE-FORMAT}/_ (even if they were built inside the Docker containers using `build.sh`). They include the recording server itself (_nextcloud-talk-recording_) as well as the Python3 dependencies that are not included in the repositories of the distributions. Note that the built dependencies change depending on the distribution type and version. + +#### Prerequisites + +Once built the packages can be installed using the package managers of the distributions, although some distributions have additional requirements that need to be fulfilled first. + +##### Debian 11 + +In Debian 11 there is no _geckodriver_ package, which is required to control Firefox from the recording server. Therefore the [PPA from Mozilla](https://launchpad.net/~mozillateam/+archive/ubuntu/ppa) needs to be setup instead before installing the packages. Although `add-apt-repository` is available in Debian 11 the PPA does not provide packages for _bullseye_, so the PPA needs to be manually added to use the packages for _focal_ (Ubuntu 20.04): +``` +apt-key adv --keyserver hkps://keyserver.ubuntu.com --recv-keys 0AB215679C571D1C8325275B9BDB3D89CE49EC21 +echo 'deb https://ppa.launchpadcontent.net/mozillateam/ppa/ubuntu focal main' > /etc/apt/sources.list.d/mozillateam-ubuntu-ppa.list +``` + +Besides that the Firefox ESR package from the PPA needs to be configured to take precedence over the one in the Debian repositories: +``` +echo ' +Package: * +Pin: release o=LP-PPA-mozillateam +Pin-Priority: 1001 +' | sudo tee /etc/apt/preferences.d/mozilla-firefox +``` + +##### Ubuntu 22.04 + +In Ubuntu 22.04 the normal Firefox package was replaced by a Snap. Unfortunately the Snap package can not be used with the default packages, so the [PPA from Mozilla](https://launchpad.net/~mozillateam/+archive/ubuntu/ppa) needs to be setup instead before installing the packages (`add-apt-repository` is included in the package `software-properties-common`): +``` +add-apt-repository ppa:mozillateam/ppa +``` + +Besides that the Firefox package from the PPA needs to be configured to take precedence over the Snap one with: +``` +echo ' +Package: * +Pin: release o=LP-PPA-mozillateam +Pin-Priority: 1001 +' | sudo tee /etc/apt/preferences.d/mozilla-firefox +``` + +#### Built packages installation + +In Debian and Ubuntu the built packages can be installed by first changing to the _recording/packaging/build/{DISTRIBUTION-ID}/deb/_ directory and then running: +``` +apt install ./*.deb +``` + +Note that given that the packages do not belong to a repository it is not possible to just install `nextcloud-talk-recording`, as the other deb packages would not be taken into account if not explicitly given. + +Besides installing the recording server and its dependencies a _nextcloud-talk-recording_ user is created to run the recording server, and a systemd service is created to start the recording server when the machine boots. + +Although it is possible to configure the recording server to use Chromium/Chrome instead of Firefox only Firefox is officially supported, so only Firefox is a dependency of the `nextcloud-talk-recording` package. In order to use Chromium/Chrome it needs to be manually installed. + +### Manual installation + +The recording server has the following non-Python dependencies: +- FFmpeg +- Firefox* +- [geckodriver](https://github.com/mozilla/geckodriver/releases) (on a [version compatible with the Firefox version](https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html)) +- PulseAudio +- Xvfb + +*Chromium/Chrome can be used too, but only Firefox is officially supported and therefore used by default. + +Those dependencies must be installed, typically using the package manager of the distribution, in the system running the recording server. + +Then, the recording server and all its Python dependencies can be installed using Python pip. Note that the recording server is not available in the Python Package Index (PyPI); you need to manually clone the git repository and then install it from there: +``` +git clone https://github.com/nextcloud/spreed +python3 -m pip install spreed/recording +``` + +The recording server does not need to be run as root (and it should not be run as root). It can be started as a regular user with `nextcloud-talk-recording --config {PATH_TO_THE_CONFIGURATION_FILE)` (or, if the helper script is not available, directly with `python3 -m nextcloud.talk.recording --config {PATH_TO_THE_CONFIGURATION_FILE)`. Nevertheless, please note that the user needs to have a home directory. + +You might want to configure a systemd service (or any equivalent service) to automatically start the recording server when the machine boots. The sources for the _.deb_ packages include a service file in _recording/packaging/nextcloud-talk-recording/debian/nextcloud-talk-recording.service_ that could be used as inspiration. + +## System setup + +Independently of how it was installed the recording server needs to be configured. Depending on the setup additional components like a firewall might also need to be setup or adjusted. + +### Recording server configuration + +When the recording server is started through its systemd service the configuration will be loaded from `/etc/nextcloud-talk-recording/server.conf`. If `nextcloud-talk-recording` is directly invoked the configuration file to use can be set with `--config XXX`. + +The configuration file must be edited to set the Nextcloud servers that are allowed to use the recording server, as well as the credentials for the recording server to use the signaling servers of those Nextcloud servers. Please refer to the sections below for the details. + +The temporary directory where the videos are stored while being recorded (and if they fail to be uploaded to the Nextcloud server) is `/tmp/`. That directory is typically a temporary file system stored in RAM, so depending on the available RAM and the number of simultaneous recordings it could affect the system or cause some recordings to suddenly fail due to running out of space. This can be customized in `backend->directory` to use a more suitable directory (for example, a directory under the home directory of the user running the recording server). + +Besides that the configuration file can be used to customize other things, like the log level, the resolution of the recorded video, the ffmpeg options to use by the encoder or the browser to perform the recording from. The encoder options have [their own documentation page](encoders.md). For the rest please refer to the comments in the configuration file itself. + +### Talk configuration + +Any Nextcloud server that will use the recording server must be explicitly allowed in the recording server configuration (except if `allowall = true` is set, but that should not be used in production). + +Each Nextcloud server needs to be configured in its own section. Any section name can be used, except the reserved names for built-in sections, like `logs`, `backend`, `signaling`... The section names must be added to `backend->backends`. + +Each backend section requires at least a `url` and a `secret`. The `url` must be set to the URL of the Nextcloud server, including the webroot, if any. The `secret` is a shared value between the Nextcloud server and the recording server used to authenticate the requests between them. You can use any string, but it is recommended to generate a random key with something like `openssl rand -hex 32`. + +Additionally other backend properties can be optionally overriden for each backend (please refer to the comments for the `backend` properties in the configuration file itself). For example, the default video resolution for the backends could be 1920x1080, but videos recorded on a specific backend could have a lower resolution of 960x540. + +In the example below comments were stripped for briefness, but it is recommended to keep them in the configuration file: +``` +[backend] +... +backends = production-cloud, experiments +... + +[production-cloud] +url = https://cloud.mydomain.com +secret = d21e7fba706c5757e25bf0419a18dfaf3bb2c89b9554b5bec138a07d20ad5bb5 + +[experiments] +url = https://testing.mydomain.com/cloud +secret = 123456 +videowidth = 960 +videoheight = 540 +``` + +The recording server to be used by a Nextcloud server must be set as well in Talk Administration settings. + +Log in the Nextcloud server as an administrator, open the Administration settings, open Talk section and under `Recording backend` set the URL of the recording server. If you are using a self-signed certificate for development purposes you will need to uncheck `Validate SSL certificate`. Besides the URL the same secret set in the recording server must be set in Talk. + +Once the URL is set it will be checked if the Nextcloud server can access the recording server, and if everything is correct you should see a valid checkmark with the text `OK: Running version XXX` (where XXX will be the recording server version). Note, however, that currently it is only checked that the recording server can be accessed, but it is not verified if the shared secret matches. + +Besides the Talk Administration settings [`upload_max_filesize`](https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize) and [`post_max_size`](https://www.php.net/manual/en/ini.core.php#ini.post-max-size) may need to be set in the PHP settings, as the maximum size of the videos uploaded to the Nextcloud server by the recording server is limited by those values. + +### Signaling server configuration + +The recording server must be allowed to access any signaling server used by the configured Nextcloud servers. Setting a signaling server in the recording server configuration does not mean that the recording server will use that signaling server, the signaling server to be used will be provided by the Nextcloud server. + +Each signaling server needs to be configured in its own section. Any section name can be used, except the reserved names for built-in sections, like `logs`, `backend`, `signaling`... The section names must be added to `signaling->signalings`. + +Each signaling section requires a `url` and an `internalsecret` (unless a common `internalsecret` is set in `signaling->internalsecret`). The `url` must be set to the URL of the signaling server (the same signaling server URL set in Talk Administration settings). The `internalsecret` is a shared value between the signaling server and the recording server used to allow the recording server to access the signaling server. This secret is unrelated to the secret used in the Talk administration settings and shared between the Nextcloud server and the recording server. This value must match the value of `clients->internalsecret` in `/etc/nextcloud-spreed-signaling/server.conf`, which is automatically generated when the signaling server is installed. Nevertheless a custom value can be set, as long as it matches in both the signaling server and the recording server. + +In the example below comments were stripped for briefness, but it is recommended to keep them in the configuration file: +``` +[signaling] +... +signalings = main-signaling, development +... + +[main-signaling] +url = https://hpb.mydomain.com/standalone-signaling +internalsecret = 0005b57434a23bf05a50dab2cddd555b532e76ffa1fb1d9904bfe513b23855bf + +[development] +url = https://192.168.57.21:18443 +internalsecret = the-internal-secret +``` + +### TLS termination proxy + +The recording server only listens for HTTP requests (the address and port is set in `http->listen` in the configuration file). It is recommended to set up a TLS termination proxy (which can be just a webserver) to add support for HTTPS connections (similar to what is done [for the signaling server](https://github.com/strukturag/nextcloud-spreed-signaling#setup-of-frontend-webserver)). + +### Firewall + +Independently of the installation method, the recording server requires some dependencies that are not typically found in server machines, like Firefox. It is highly recommended to setup a firewall that prevents any access from the outside to the machine, except those strictly needed by the recording server (and, of course, any additional service that might be needed in the machine, like SSH). + +This is specially relevant when the recording server runs in a machine directly connected to the Internet, although it is of less concern when running in an internal network or in a virtual machine with a bridged network, as in those cases the external access would be already limited. + +The recording server acts similar to a regular participant in the call, so the firewall needs to allow access to the Nextcloud server and the HPB. Independently of whether the firewall is set in the recording server machine itself or somewhere else these are the connections that need to be allowed from the recording server: +- Nextcloud server using HTTPS (TCP on port 443 of the Nextcloud server). +- HPB using HTTPS (TCP on port 443 of the signaling server). + The HTTPS connection must be upgradeable to a WebSocket connection. +- HPB using UDP. + The recording server connects to a port in the range 20000-40000 (or whatever range is configured in Janus, the WebRTC gateway), while the WebRTC gateway may connect on any port of the recording server. + +Depending on the setup the recording server might also need to access the STUN server and/or the TURN server, although typically it will not be needed (especially if both the HPB and the recording server can directly access each other): +- STUN server using UDP (port depends on the STUN server configuration). +- TURN server using UDP or TCP (protocol and port depend on the TURN server configuration). + +## Testing and troubleshooting + +Once the configuration is done it is recommended to record a call to verify that everything works as expected. Recording server log level should be preferably set to `10` (debug) during the verification to have the most information if something fails: +- Start a call as a moderator (only moderators can record a call) +- Start the call recording +- Once the recording has started speak for some seconds, preferably with video enabled +- Stop the recording +- Eventually you will receive a notification that the recording is available +- Check the recording + +If something did not work as expected please check below for some possible causes. + +### The recording is stuck in _Starting_ but never starts nor fails + +It is very likely that the recording server could not send the request to mark the recording as started or failed. It is typically one of the cases below: +- The shared secret between the Nextcloud server and the recording server is not the same (`Checksum verification failed` is shown in the logs of the recording server). +- The Nextcloud server is using a self-signed certificate (`certificate verify failed: self signed certificate` is shown in the logs of the recording server). The recording server can be configured to skip verification of the Nextcloud server certificate with the `skipverify` setting in `server.conf`. However, please note that this should be used only for development and a proper certificate should be used in production. + +### The recording fails to be started + +It is typically one of the cases below: +- The shared secret between the signaling server and the recording server is not the same (`Authentication failed for signaling server` is shown in the logs of the recording server). +- The recording server was not able to connect to the signaling server. Both the logs of the recording server and the signaling server may provide some hints, although the problem is typically related to the firewall. +- The ffmpeg configuration is invalid (`recorder ended unexpectedly` is shown in the logs of the recording server; note that this error could appear in other (strange) cases too, like if ffmpeg crashes). The specific cause can be seen in the messages tagged as `nextcloud.talk.recording.Service.recorder`. + +### The recording fails to be uploaded + +In this case the explanation is probably found in the Nextcloud server logs. Typically the problem is that the recording size exceeded the values configured for `upload_max_filesize` (`The uploaded file exceeds the upload_max_filesize directive in php.ini` is shown in the logs of the Nextcloud server) or `post_max_size` (`OCA\\Talk\\Controller\\RecordingController::store(): Argument #1 ($owner) must be of type string, null given` is shown in the logs of the Nextcloud server). + +If a video could not be uploaded it will be still kept in the recording server under `/{TEMPORARY-DIRECTORY-FOR-RECORDINGS}/{CONVERSATION-TOKEN}`. Note that the default temporary directory for recordings is `/tmp/`, so a recorded video that could not be uploaded may be removed if the machine is restarted. The conversation token is the part after `/call/` in the URL of the conversation. + +### The recording was uploaded, but the recording shows that the connection could not be established with other participants + +The recording server was not able to connect to Janus, the WebRTC gateway (or, if direct access to Janus is not possible, to the TURN server). Both the logs of the recording server and the HPB (signaling server and Janus) may provide some hints, although the problem is typically related to the firewall. + +In some rare cases it can be related as well to the network topology and how the browsers handle WebRTC connections; in those cases changing the browser used to do the recordings may solve the issue. + +To diagnose this problem and check which WebRTC candidates are being tried to establish the connection between the recording server and Janus it is possible to access the browser window being used to do a recording using `x11vnc`. It must be launched as the same user that started the X server, `nextcloud-talk-recording`. As that user does not have a login shell it needs to be specified when running `su`: `su - nextcloud-talk-recording --shell /bin/bash --command "x11vnc -rfbport 5900 -display :XXX"`, where `XXX` is the display number used by the X server used for the recording. Each recording has its own X server, so for simplicity it is recommended to test this when there is a single recording; in that case `-display :0` will typically connect to the expected X server. For extra security it would be recommended to tunnel the VNC connection through SSH. Please refer to `x11vnc` help. + +Once `x11vnc` is running a VNC viewer can be started in a different machine that has a graphic server and access to the recording server machine to see and interact with the browser window. The browser will be running in kiosk mode, so there will be no address bar nor menu. However, in the case of Firefox, the WebRTC candidates can be checked by first opening a new tab with `Ctrl+T` and then, in the new tab, "opening" the address bar with `Ctrl+L` and then typing `about:webrtc` to load the helper page with the WebRTC connections. + +If `x11vnc` is not started with `-forever` or `-shared` the server should be automatically closed once the viewer is closed. Nevertheless, it is highly recommended to verify that it was indeed the case. From e6cd521ad3e5f66638ec005e4c9179e7f5ea9613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 22 Mar 2023 22:44:06 +0100 Subject: [PATCH 25/25] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/docs/encoders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recording/docs/encoders.md b/recording/docs/encoders.md index 72dfaa95c66..810ab026cf6 100644 --- a/recording/docs/encoders.md +++ b/recording/docs/encoders.md @@ -12,7 +12,7 @@ Nevertheless, please note that VP8 and Opus are just the default ones and that t A benchmark tool is provided to check the resources used by the recorder process as well as the quality of the output file using different configurations. -The benchmark tool does not record an actual call; it plays a video file and records its audio and video (or, optionally, only its audio). This makes possible to easily compare the quality between different configurations, as they can be generated from the same input. There is no default input file, though; a specific file must be provided. +The benchmark tool does not record an actual call; it plays a video file and records its audio and video (or, optionally, only its audio). This makes it possible to easily compare the quality between different configurations, as they can be generated from the same input. There is no default input file, though; a specific file must be provided. ### Usage example