Best way to "release" closed source ROS2 packages
Hello fellow robo-enthusiasts,
our closed (~private) source project uses ROS2 packages arranged into on-site GIT repositories. We have some basic automation going on (local Jenkins instance, fragile bits of ros_buildfarm stitched together ages ago). Over time, the project logically hit limitations of our current infrastructure. From top of my head:
- arranging GIT repositories using
git submodule
fails in a scenario, where the same package would be brought in by more than one submodule.colcon
then simply refuses to cope with this duplicity and manual "pre-build" intervention is needed. Devs hate that. Cleaning up architecture quickly leads to this problem (single shared interface repo with Actions, Services etc.) - assembling "releases" (to try on a live hardware for example) is cumbersome, partially because of things mentioned above, as well as the need to handle live source code (creating security concerns when 3rd party hardware is used, for example when doing a demo)
Having experience with different software projects and domains, my first thought was that we need packaging system to meet our needs. Then, we would just apt-get
our packages by version, the same way we get ROS2
stock ones.
In reality, so far I have spent more than a week finding out how to get there. Now I kinda fear there is no easy way. So this is my cry for help and guidance - what is the best path to take? What am I missing?
Specifically, we only need to build ROS 2
packages for foxy
, ubuntu:focal
targets. Because I tend to stumble into ROS 1 specific docs, not applicable for ROS 2 without detailed knowledge.
What I tried
PATH A: manual APT / DEB package creation.
According to a note found in ROS2 documentation, I tried bloom-generate rosdebian
=> fakeroot debian/rules binary
route. After struggling with rosdep
configuration with packages depending on another private packages, I managed to get to the fakeroot step, but it fails for some of our packages in a weird way. I managed some progress, but it feels painful. Specifically, I see errors about pthread
library missing (while CMake colcon build ends up being fine)
PATH B: creating full local ros buildfarm clone
Because we cannot easily use the "public" open source buildfarm, I thought I'll try to recreate private one. So far, this has also been a rough ride, while trying to follow existing documentation. Because I must not tinker with the existing Jenkins instance to not disrupt rest of the team, I created my own locally in a Docker container. However, the ros_buildfarm
scripting gives me all kinds of weird responses, leading me to believe I won't be able to force foxy
releases this way. My other gut feeling tells me the scripting probably expects older versions of Jenkins than I am providing.
Anyone can help me to choose the right path? Then I can probably ask specific questions about the errors I see, but maybe I just plainly chose a bad way altogether.
Asked by Aldor on 2021-08-17 10:44:13 UTC
Answers
For ROS 2 you can basically use any packaging mechanism you would use for any other proprietary software. We have standardized to use the install target and if you write your CMake code cleanly the install directory should be relocatable and can even be redistributed by tarballs. This is one of the mechanisms by which we offer to install ROS 2. Aka what we call the "fat" archive. http://docs.ros.org/en/rolling/Installation/Ubuntu-Install-Binary.html
You can also create your own debian packages. You can manually follow the debian process: https://www.debian.org/doc/manuals/maint-guide/ and do it all manually.
You can leverage bloom to generate the metadata and then manually build the sourcedeb and binarydeb using git-buildpackage or dpkg-buildpackage manually. You will need to learn and understand the debian build pipelines and if you want to do several layers of packages or repositories you will need to munge some manual rosdep keys because you're not using a rosdistro to keep track of your released dependencies.
Depending on what you're looking to do you can stand up a whole instance of our buildfarm. https://github.com/ros-infrastructure/ros_buildfarm If you're planning to produce a lot of packages it's worth considering, but it's a lot of work to get setup.
There's no "correct" answer to this generically. My answers are reoughly in order of complexity. The more complex solutilons the more automation is available for repeated operations. But in general packaging is non-trivial and there's no simple solution that will work for anyone.
There are many other approaches, such as using docker images as well. They have different tradeoffs. There are a lot of tradeoffs of the level of modularity that you choose, many small packages, one large package. you trade off flexibility for your users vs complexity.
I would recommend looking at general software delivery practices. ROS 2 packages are relatively well behaved generally with respect to requrements for packaging and can be treated like most other python or cmake packages. You just have to make sure to build them in the right order with their dependencies availalble.
Asked by tfoote on 2021-08-25 02:00:13 UTC
Comments
Not an answer, but:
IIRC, you cannot deploy a
ros_buildfarm
instance using Docker. It "needs" a bare metal OS / VM ("needs" in quotes, as it's obviously possible to get it to run inside a container, but if you're just starting out, that may not be the most efficient way to get it going).Asked by gvdhoorn on 2021-08-17 11:48:31 UTC