Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mega: Resolve conflicting Debian packages #15

Open
2 of 4 tasks
mtlynch opened this issue Nov 17, 2022 · 5 comments
Open
2 of 4 tasks

Mega: Resolve conflicting Debian packages #15

mtlynch opened this issue Nov 17, 2022 · 5 comments

Comments

@mtlynch
Copy link
Contributor

mtlynch commented Nov 17, 2022

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:

  1. Create a custom debian package for libnice10
  2. Publish a new release of janus that depends on libnice10
  3. 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:

  1. We add our custom tinypilot apt repo
  2. We specify in the apt task of our Ansbile role to install something like janus=1.04
  3. apt sees janus=1.0.4 in TinyPilot's apt repo
  4. apt sees that janus=1.0.4 depends on libnice10=0.1.18
  5. apt sees libnice10=0.1.18 in TinyPilot's apt repo
  6. 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)
  7. 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

  • Probably doesn't exist

Subtickets

@mtlynch
Copy link
Contributor Author

mtlynch commented Nov 17, 2022

@jdeanwallace @jotaen4tinypilot - Can you review and let me know your thoughts?

I thought this would be small enough for me to handle on my own, but I'm realizing it's larger in scope than I realized, and it's something we need to figure out before we release H.264.

@jdeanwallace
Copy link
Collaborator

Nice write up. Here are some of my thoughts:

  1. From the Janus repo readme, under dependencies:

    libnice (at least v0.1.16 suggested, v0.1.18 recommended)

    libnice10 (0.1.16) is available on buster-backports and bullseye apt repos. Can we consider downgrading libnice10 from 0.1.18 to 0.1.16?

  2. D. Find a trustworthy apt repo for Janus

    When building janus, we currently set a few flags to remove some unnecessary functionality. I suspect that if we use an already available Janus package, we'll get everything but the kitchen sink. Not a deal breaker though.

  3. In terms of installing janus & friends, option B seems like only a slight improvement on option C. If so, we can always start with the easier option C and then upgrade to B, if needed.

  4. A. Host our own apt repo

    I'm unsure about how smart/dumb apt is in finding/resolving dependencies. I'll need to play around with it a bit to see how it behaves.

  5. 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.

    I agree that this would be ugly, but at least these hacks wouldn't live in our code forever because we should be able to push users down a specific download path (i.e., 2.4.1 -> 2.4.8 -> 5.10) 😬

@mtlynch
Copy link
Contributor Author

mtlynch commented Nov 21, 2022

Oh, I hadn't really understood what the backports repo was, but from reading about them a little more, they seem like a good option.

If we could install Janus (and possibly other dependencies) from backports, that would be much better than having to maintain our own Debian package, which has been eating up a lot of our dev time.

@jdeanwallace - Can you look into tiny-pilot/ansible-role-ustreamer#77 once you've got the gatekeeper stuff wrapped up?

@jotaen4tinypilot
Copy link

Are we certain that libnice10 comes pre-installed? At least on a 2022-09-22 release of Raspberry Lite (!) Bullseye, none of the packages seem to be there:

root@raspberrypi:/home/pi# lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 11 (bullseye)
Release:	11
Codename:	bullseye

root@raspberrypi:/home/pi# dpkg --list libnice*
dpkg-query: no packages found matching libnice*

root@raspberrypi:/home/pi# dpkg --list libsrtp*
dpkg-query: no packages found matching libsrtp*

root@raspberrypi:/home/pi# dpkg --list libwebsockets*
dpkg-query: no packages found matching libwebsockets*

I haven’t checked the full (non-lite) install, though, so it might be pre-installed there. All three packages are available and installable through the default apt repositories.

I suppose it’s still better to have that sorted out in any event, just to avoid nasty problems down the line.

Unfortunately, I’m not that deeply into this topic currently, so in order to contribute, I would need to invest some upfront time to learn more about the problem. I’m happy to do that, I just wanted to check beforehand whether that’s worthwhile, given that @jdeanwallace seems to have a good clue already?

@mtlynch
Copy link
Contributor Author

mtlynch commented Nov 22, 2022

Yeah, I'm not sure how it gets installed, but I've definitely had conflicts with libnice10 when I test on Bullseye Lite. Maybe something earlier in the install process installs libnice10 as a side effect?

I think the best option at the moment is to explore whether we can just install using the official packages in the backports repo. Because if that's possible, then we save ourselves a lot of work now and a lot of ongoing maintenance work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants