-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Build uStreamer Debian package with Janus plugin (#6)
Resolves #3 This PR builds a uStreamer Debian package (with Janus plugin) in CI. The reason why we couldn't just use the [official(?) uStreamer Debian package](https://salsa.debian.org/reedy/ustreamer/) is because it doesn't compile the Janus plugin (which we need for WebRTC support). Now we can avoid building uStreamer from source every time TinyPilot is installed or updated. You can test the uStreamer Debian package on a device via this [scratch TinyPilot Pro build bundle](https://app.circleci.com/pipelines/github/tiny-pilot/tinypilot-pro/2801/workflows/ba68bf47-f01c-4240-a008-6456f956dca4/jobs/20659/artifacts). Notes: * We compile the uStreamer Debian package for both [`armhf` and `amd64` architectures](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-78a8a19706dbd2a4425dd72bdab0502ed7a2cef16365ab7030a5a0588927bf47R33-R38) because the `amd64` version will be used when testing the uStreamer Ansible role in CI (using molecule) and the `armhf` version will be used when installing TinyPilot on a device. * FYI, compiling for multiple architectures produces Debian packages in the following [directory structure](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-78a8a19706dbd2a4425dd72bdab0502ed7a2cef16365ab7030a5a0588927bf47R46-R49): * `/build/linux_arm_v7/*.deb` * `/build/linux_amd64/*.deb` As opposed to just `/build/*.deb` when compiling for a single architecture. * Most of the [lintian code](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-78a8a19706dbd2a4425dd72bdab0502ed7a2cef16365ab7030a5a0588927bf47R52-R80) is copy/pasted from [TinyPilot Community repo](https://github.com/tiny-pilot/tinypilot/blob/b984ab93a58533220ad6358831ce8e405810db8f/.circleci/continue_config.yml#L97-L122), besides the [loop to check multiple Debian packages](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-78a8a19706dbd2a4425dd72bdab0502ed7a2cef16365ab7030a5a0588927bf47R71-R80). * Seeing as [uStreamer makes use of a simple `v${MAJOR}.${MINOR}` versioning schema](https://github.com/tiny-pilot/ustreamer/tags), I used that (without the `v` prefix) as the Debian package version with an added a timestamp revision number to allow for the Debian package to be updated even when the uStreamer version has stayed the same. The resulting uStreamer Debian package versioning schema being [`MAJOR.MINOR-YYYYMMDDhhmmss`](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-dd2c0eb6ea5cfc6c4bd4eac30934e2d5746747af48fef6da689e85b752f39557R63) * Seeing as Docker doesn't support dynamic `WORKDIR` values based on a command's output, I stole these ([1](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-dd2c0eb6ea5cfc6c4bd4eac30934e2d5746747af48fef6da689e85b752f39557R46-R70), [2](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-dd2c0eb6ea5cfc6c4bd4eac30934e2d5746747af48fef6da689e85b752f39557R140-R146)) clever workarounds from Michael's [PR](https://github.com/tiny-pilot/tinypilot/pull/1352/files#diff-d3aed37eb2a4156ced425c7bcab79741d1234d58d182d91099b780c3c3136ce4R31-R53). * The [copyright notice I've used here](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-eb1289be1c2cdfc905cecdba0c6810aa4d987d52e34f9dee681c1ff9cd69c34fR1-R2) was given to me my Michael via email * When we built uStreamer on the device, we technically [only ever ran `make`](https://github.com/tiny-pilot/ansible-role-ustreamer/blob/b1017f8f4436071b5d8dcf812ee351fc846e1fa6/tasks/main.yml#L153-L161) and never `make install`. This Debian package builds using `make && make install` which results in the binary being moved to `bin/ustreamer`. I thought running the `make install` is a good thing, so I just [added a symlink (`/opt/ustreamer/ustreamer -> bin/ustreamer`)](https://github.com/tiny-pilot/ustreamer-debian/pull/6/files#diff-fe915a3611d3df024aa33709affc37ff7a049adc629d69f2f0fe0dd063ad155fR1-R2) to maintain TinyPilot's path to uStreamer. Helpful resources on creating Debian packages: * https://vincent.bernat.ch/en/blog/2019-pragmatic-debian-packaging * https://github.com/vincentbernat/pragmatic-debian-packages/ * https://salsa.debian.org/reedy/ustreamer/ * https://github.com/tiny-pilot/tinypilot/pull/1352/files <a data-ca-tag href="https://codeapprove.com/pr/tiny-pilot/ustreamer-debian/6"><img src="https://codeapprove.com/external/github-tag-allbg.png" alt="Review on CodeApprove" /></a>
- Loading branch information
1 parent
249e368
commit 258e1e4
Showing
10 changed files
with
250 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Debian doesn't want packages to install to /opt, but it also doesn't give | ||
# clear guidance on where they *should* go. It's too much churn at this point to | ||
# change, so we're going to ignore this. | ||
dir-or-file-in-opt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# syntax=docker/dockerfile:1.4 | ||
# Enable here-documents: | ||
# https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#here-documents | ||
|
||
FROM debian:bullseye-20220328-slim AS build | ||
|
||
RUN set -x && \ | ||
apt-get update && \ | ||
DEBIAN_FRONTEND=noninteractive apt-get install -y \ | ||
debhelper \ | ||
dpkg-dev \ | ||
devscripts \ | ||
git \ | ||
build-essential \ | ||
wget \ | ||
gnupg | ||
|
||
# Add bullseye-backports apt suite to later install janus dependency. | ||
RUN cat | bash <<'EOF' | ||
set -ex | ||
# Add keyring. | ||
wget \ | ||
--output-document - \ | ||
https://ftp-master.debian.org/keys/archive-key-11.asc | \ | ||
gpg \ | ||
--dearmor > \ | ||
/usr/share/keyrings/bullseye-archive-keyring.gpg | ||
# Add repository. | ||
echo 'deb [signed-by=/usr/share/keyrings/bullseye-archive-keyring.gpg] http://deb.debian.org/debian bullseye-backports main' > \ | ||
/etc/apt/sources.list.d/bullseye-backports.list | ||
# Update package index. | ||
apt-get update | ||
EOF | ||
|
||
# Docker populates this value from the --platform argument. See | ||
# https://docs.docker.com/build/building/multi-platform/ | ||
ARG TARGETPLATFORM | ||
|
||
ARG PKG_NAME='ustreamer' | ||
ARG PKG_VERSION='5.38' | ||
|
||
# This should be a timestamp, formatted `YYYYMMDDhhmmss`. That way the package | ||
# manager always installs the most recently built package. | ||
ARG PKG_BUILD_NUMBER | ||
|
||
# Docker's platform names don't match Debian's platform names, so we translate | ||
# the platform name from the Docker version to the Debian version and save the | ||
# result to a file so we can re-use it in later stages. | ||
RUN cat | bash <<'EOF' | ||
set -exu | ||
case "${TARGETPLATFORM}" in | ||
'linux/amd64') | ||
PKG_ARCH='amd64' | ||
;; | ||
'linux/arm/v7') | ||
PKG_ARCH='armhf' | ||
;; | ||
*) | ||
echo "Unrecognized target platform: ${TARGETPLATFORM}" >&2 | ||
exit 1 | ||
esac | ||
echo "${PKG_ARCH}" > /tmp/pkg-arch | ||
echo "${PKG_NAME}-${PKG_VERSION}-${PKG_BUILD_NUMBER}-${PKG_ARCH}" > /tmp/pkg-id | ||
EOF | ||
|
||
# We ultimately need the directory name to be the package ID, but there's no | ||
# way to specify a dynamic value in Docker's WORKDIR command, so we use a | ||
# placeholder directory name to assemble the Debian package and then rename the | ||
# directory to its package ID name in the final stages of packaging. | ||
WORKDIR /build/placeholder-pkg-id | ||
|
||
RUN git \ | ||
clone \ | ||
--branch "v${PKG_VERSION}" \ | ||
--depth 1 \ | ||
https://github.com/tiny-pilot/ustreamer.git \ | ||
. | ||
|
||
COPY debian debian | ||
|
||
WORKDIR debian | ||
|
||
RUN set -x && \ | ||
PKG_ARCH="$(cat /tmp/pkg-arch)" && \ | ||
set -u && \ | ||
cat >control <<EOF | ||
Source: ${PKG_NAME} | ||
Section: video | ||
Priority: optional | ||
Maintainer: TinyPilot Support <[email protected]> | ||
Build-Depends: debhelper (>= 11), | ||
dh-exec, | ||
libevent-dev, | ||
libjpeg-dev, | ||
uuid-dev, | ||
libbsd-dev, | ||
janus-dev, | ||
libasound2-dev, | ||
libspeex-dev, | ||
libspeexdsp-dev, | ||
libopus-dev | ||
|
||
Package: ${PKG_NAME} | ||
Architecture: ${PKG_ARCH} | ||
Depends: \${shlibs:Depends}, \${misc:Depends} | ||
Homepage: https://github.com/tiny-pilot/ustreamer | ||
Description: Lightweight and fast MJPEG-HTTP streamer | ||
µStreamer is a lightweight and very quick server to stream MJPEG video | ||
from any V4L2 device to the net. All new browsers have native | ||
support of this video format, as well as most video players such as | ||
mplayer, VLC etc. µStreamer is a part of the PiKVM project designed to | ||
stream VGA and HDMI screencast hardware data with the highest resolution | ||
and FPS possible. | ||
EOF | ||
|
||
RUN cat >changelog <<EOF | ||
${PKG_NAME} (${PKG_VERSION}-${PKG_BUILD_NUMBER}) bullseye; urgency=medium | ||
|
||
* Latest µStreamer release. | ||
|
||
-- TinyPilot Support <[email protected]> $(date '+%a, %d %b %Y %H:%M:%S %z') | ||
EOF | ||
|
||
# Install build dependencies based on Debian control file. | ||
RUN mk-build-deps \ | ||
--tool 'apt-get --option Debug::pkgProblemResolver=yes --no-install-recommends -qqy' \ | ||
--install \ | ||
--remove \ | ||
control | ||
|
||
# Allow Janus C header files to be included when compiling third-party plugins. | ||
# https://github.com/tiny-pilot/ansible-role-tinypilot/issues/192 | ||
RUN sed \ | ||
--in-place \ | ||
's/^#include "refcount\.h"$/#include "\.\.\/refcount\.h"/g' \ | ||
/usr/include/janus/plugins/plugin.h | ||
|
||
# Rename the placeholder build directory to the final package ID. | ||
WORKDIR /build | ||
RUN set -x && \ | ||
PKG_ID="$(cat /tmp/pkg-id)" && \ | ||
mv placeholder-pkg-id "${PKG_ID}" && \ | ||
cd "${PKG_ID}" && \ | ||
DH_VERBOSE=1 dpkg-buildpackage --build=binary | ||
|
||
FROM scratch as artifact | ||
|
||
COPY --from=build "/build/*.deb" ./ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
11 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/usr/bin/make -f | ||
|
||
# Set all dpkg-architecture variables (i.e., ${DEB_HOST_MULTIARCH}, etc.). | ||
include /usr/share/dpkg/architecture.mk | ||
|
||
# Prevent debhelper from generating an extra package with debug symbols. | ||
export DEB_BUILD_OPTIONS=noddebs | ||
|
||
export PREFIX=/opt/ustreamer | ||
|
||
%: | ||
dh $@ | ||
|
||
override_dh_usrlocal: | ||
|
||
override_dh_auto_build: | ||
dh_auto_build -- WITH_JANUS=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Copyright (C) 2018-2022 by Maxim Devaev [email protected] | ||
Copyright (c) 2023 TinyPilot, LLC <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/dh-exec | ||
janus/libjanus_ustreamer.so usr/lib/${DEB_HOST_MULTIARCH}/janus/plugins/ | ||
LICENSE opt/ustreamer/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
opt/ustreamer/bin/ustreamer opt/ustreamer/ustreamer | ||
opt/ustreamer/bin/ustreamer-dump opt/ustreamer/ustreamer-dump |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
|
||
# Exit script on first failure. | ||
set -e | ||
|
||
# If a .git directory exists, the previous version was installed with the legacy | ||
# installer, so wipe the install location. | ||
if [[ -d /opt/ustreamer/.git ]]; then | ||
rm -rf /opt/ustreamer | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters