Overview
TinyPilot's Janus Debian package conflicts with three other packages in a way that might create problems for us in the future.
Details
Janus' package conflicts
Our Janus package currently conflicts with (at least) three other Debian packages:
- libnice10
- libsrtp2-1
- libwebsockets16
libnice10 is the most troublesome because there is a libnice10 package available from standard Raspbian apt repos, whereas I don't think the others are available. Worse, I believe libnice10 is installed by default in Raspbian Bullseye.
The conflict is that in order to function, Janus needs shared libraries from the other packages to be in their expected location. For example, the Janus package places a file at /usr/lib/arm-linux-gnueabihf/libnice.so.10. But then the real libnice10 package also wants to place a file there. If both packages are trying to place a file in the same location, there's a conflict.
The proper thing to do is to declare the conflict in the package metadata. I didn't understand this before, so I removed the conflict line, but it turned out that just pushed the failure later in the install process when apt realizes that another package already owns a file that the Janus package is trying to install.
Why this is a problem
In the short term, this prevents Bullseye users from installing TinyPilot or running the uStreamer Ansible role.
In the long term, a poor strategy choice here could create headaches for us later.
Our custom debian package for janus=1.0.1 conflicts with libnice10. A naive solution to resolve this would be:
- Create a custom debian package for libnice10
- Publish a new release of janus that depends on libnice10
- Make sure to install our custom libnice10 before installing janus
For users who installed Janus while H264 was in beta, they'll fail the above sequence. They won't be able to install our new libnice10 package because it will conflict with their existing janus package. And they won't be able to install our new janus package because it will have a dependency on our custom build of libnice10, which apt won't know how to find.
Maybe we have special logic to remove old versions of janus before installing libnice10, but that's a bit ugly. And then if we ever have to unbundle libsrtp2-1 or libwebsockets16, we're back to the same problem.
Potential solutions
A. Host our own apt repo
I think (but don't know for sure) that if we host our own apt repo, we can tell apt to install sets of packages rather than having them install one-by-one, as we're currently doing.
That should solve the circular dependency problem because if we have janus=1.0.1 that conflicts with libnice10, what I expect will happen is:
- We add our custom tinypilot apt repo
- We specify in the
apt task of our Ansbile role to install something like janus=1.04
- apt sees
janus=1.0.4 in TinyPilot's apt repo
- apt sees that
janus=1.0.4 depends on libnice10=0.1.18
- apt sees
libnice10=0.1.18 in TinyPilot's apt repo
- apt automatically removes
janus=1.0.1 in anticipation of upgrading to janus=1.0.4 (I think this is apt's behavior but I'm not 100% sure)
- apt installs both
janus=1.0.4 and libnice=0.1.18
Advantages
- Gives us flexibility
- Might be useful if we decide to distribute private packages via a private repo in the future
- Plays nicely with Ansible
- We only have to unbundle libnice10 now because it would be easy to unbundle the others in the future without complicated workarounds for conflicts
Disadvantages
- More complex than just building one-off .deb files and hosting them in Github releases
- More opportunities to shoot ourselves in the foot if we screw up some part of it
B. Install multiple Debian packages at once
It's possible that we can install sets of Debian packages without an apt repo. dpkg accepts multiple packages, so maybe we can just do something like:
dpkg --install \
janus_1.0.1-20221104_armhf.deb \
libnice10_0.1.18-202211161620_armhf.deb
It doesn't seem like we can do it from Ansible's apt module because that module supports only a single path at a time, so we'd have to use shell and command and take care of downloading the .deb files in separate Ansible plays.
Advantages
- We don't have to host our own apt repo
- We only have to unbundle libnice10 now because it would be easy to unbundle the others in the future without complicated workarounds for conflicts
Disadvantages
- We can't use the
apt module in Ansible
- Our Ansible logic would be pretty complicated because we'd have to download and install every package on every Ansible run or else do something clever to figure out which packages need to be updated
- We'd have to do
shell or command instead of the standard apt to install multiple packages in a single dpkg install
C. Install debian packages one by one
The other possibility is that we just keep installing .deb packages one by one like we're currently doing.
Advantages
- Simple to do in Ansible
- We can keep using standard
apt Ansible module
Disadvantages
- We either have to let Community/beta users fail to upgrade or implement a workaround that will uninstall the conflicting version of
janus=1.0.1
- We'd want to unbundle libwebsockets and librtsp now to avoid complicated conflicts in the future
D. Find a trustworthy apt repo for Janus
I don't think one exists, but it might be worth doing another quick check to avoid duplicating effort.
Advantages
- Much less maintenance burden for us
Disadvantages
Subtickets
Overview
TinyPilot's Janus Debian package conflicts with three other packages in a way that might create problems for us in the future.
Details
Janus' package conflicts
Our Janus package currently conflicts with (at least) three other Debian packages:
libnice10 is the most troublesome because there is a libnice10 package available from standard Raspbian apt repos, whereas I don't think the others are available. Worse, I believe libnice10 is installed by default in Raspbian Bullseye.
The conflict is that in order to function, Janus needs shared libraries from the other packages to be in their expected location. For example, the Janus package places a file at
/usr/lib/arm-linux-gnueabihf/libnice.so.10. But then the real libnice10 package also wants to place a file there. If both packages are trying to place a file in the same location, there's a conflict.The proper thing to do is to declare the conflict in the package metadata. I didn't understand this before, so I removed the conflict line, but it turned out that just pushed the failure later in the install process when apt realizes that another package already owns a file that the Janus package is trying to install.
Why this is a problem
In the short term, this prevents Bullseye users from installing TinyPilot or running the uStreamer Ansible role.
In the long term, a poor strategy choice here could create headaches for us later.
Our custom debian package for
janus=1.0.1conflicts withlibnice10. A naive solution to resolve this would be:For users who installed Janus while H264 was in beta, they'll fail the above sequence. They won't be able to install our new
libnice10package because it will conflict with their existingjanuspackage. And they won't be able to install our newjanuspackage because it will have a dependency on our custom build oflibnice10, which apt won't know how to find.Maybe we have special logic to remove old versions of janus before installing libnice10, but that's a bit ugly. And then if we ever have to unbundle libsrtp2-1 or libwebsockets16, we're back to the same problem.
Potential solutions
A. Host our own apt repo
I think (but don't know for sure) that if we host our own apt repo, we can tell
aptto install sets of packages rather than having them install one-by-one, as we're currently doing.That should solve the circular dependency problem because if we have
janus=1.0.1that conflicts withlibnice10, what I expect will happen is:apttask of our Ansbile role to install something likejanus=1.04janus=1.0.4in TinyPilot's apt repojanus=1.0.4depends onlibnice10=0.1.18libnice10=0.1.18in TinyPilot's apt repojanus=1.0.1in anticipation of upgrading tojanus=1.0.4(I think this is apt's behavior but I'm not 100% sure)janus=1.0.4andlibnice=0.1.18Advantages
Disadvantages
B. Install multiple Debian packages at once
It's possible that we can install sets of Debian packages without an apt repo.
dpkgaccepts multiple packages, so maybe we can just do something like:It doesn't seem like we can do it from Ansible's apt module because that module supports only a single
pathat a time, so we'd have to useshellandcommandand take care of downloading the.debfiles in separate Ansible plays.Advantages
Disadvantages
aptmodule in Ansibleshellorcommandinstead of the standardaptto install multiple packages in a singledpkginstallC. Install debian packages one by one
The other possibility is that we just keep installing
.debpackages one by one like we're currently doing.Advantages
aptAnsible moduleDisadvantages
janus=1.0.1D. Find a trustworthy apt repo for Janus
I don't think one exists, but it might be worth doing another quick check to avoid duplicating effort.
Advantages
Disadvantages
Subtickets