Errors creating snap with ros: the rosdep view is empty

Having a little trouble packaging up my ROS workspace. It feels like a path issue somewhere but I can’t track it down.

When we start the snap, we get a few errors:

cannot launch node of type [our_package/our_rosbridge_suite_node] in package [our_package]
the rosdep view is empty: call 'sudo rosdep init' and 'rosdep update'

I have a hunch that these are related but troubleshooting rosdep feels like the easier place to start troubleshooting since it’s probably a bit more universal. Everything works fine outside of our snap; in fact, roscore starts from within the snap and we can launch nodes as another user.

After launching bash in the context of my snap (thanks for the tip, Kyle!) I was able to run rosdep update. It updated source lists and reported:

updated cache in /home/my-user/snap/my-snap/x1/ros/rosdep/sources.cache

After this, running rosdep check rosbridge_server returned:

ERROR: Rosdep experienced an internal error.
Please go to the rosdep page... blah blah blah

rosdep version: 011.8

Bad installer [apt]: [Errno 2] No such file or directory

Is it missing permission to install dependencies? Something else? Appreciate any advice.

Hey there @cg-bbi. rosdep is only really utilized by Snapcraft at build-time, not run-time. Indeed, if you’re creating a snap with strict confinement it won’t have permission to install anything. The rosdep view will probably always be empty, which means it’s probably not the best place to start troubleshooting.

Are you able to actually find the node installed correctly in the snap itself (or the prime directory)? Any chance this is due to a lack of install rules?

Hey Kyle! You’re fast. My confinement is set to devmode and I think my install rules are correct at this point. We have two packages, one C++ and the other Python. Our roslaunch file is bundled with the Python package and refers back to the C++.

The C++ install rules essentially look like this:

install(DIRECTORY launch
          DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

install(DIRECTORY config
          DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

install(TARGETS our_executable_node_name
          ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
          LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
          RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

And then the Python one is a bit simpler:

install(DIRECTORY launch
          DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

To answer your other question, I’m not sure whether what I see in the prime directory is correct. I see things in there, folders show update times that match my builds.

Does your Python package contain no executables?

Our robotics engineer reports, “That is correct. We execute the .py file directly.”

Think this could be contributing?

How is the .py you’re executing getting into the snap? I see no install rules placing any .py files.

Take a look at the rospy tutorials as an example, although I still tend to use the normal install, like this. Not sure what sort of shebang rewriting catkin_install_python does.

¯\(ツ)

Great question! I’m new to ROS from this side of things, working on that that now. I assumed it was… something something launch file. We’re reviewing the CMakeLists.txt files right now and confirmed that you’re right, we’re missing some stuff. We’re fixing this stuff and I’ll report back soon.

Haha, no problem!

The launch file is just an XML file, or in your case it seems to be a directory containing related XML launch files. However, typically the launch directory does not contain executables (scripts or otherwise), and if so, they’re being installed into the wrong locations.

Getting closer. We’ve got our Python scripts installing but I’m running into the error:

ImportError: no module named actionlib

Sounds pretty crazy, since actionlib is part of vanilla ROS, right?

From outside my snap, rospack find actionlib returns /opt/ros/kinetic/share/actionlib. Meanwhile, from within the snap, it cannot be found.

The import one line earlier, rospy, does resolve correctly, same path as actionlib outside the snap and /snap/my-snap-name/x14/opt/ros/kinetic/share/ inside. I know that troubleshooting ROS isn’t really your job here but any chance you can point me in the right direction? I’ve been looking for examples of working snaps that use actionlib but have been unable to find any.

One more: we misunderstood what the catkin plugin would install. We thought actionlib came with ros-core, it’s actually part of ros-base, so adding ros-kinetic-actionlib to our stage-packages fixed that. We’re getting some more errors about our Python scripts, need to fix some more paths.

We’re still seeing that the rosdep view is empty error but we’ll keep troubleshooting these other errors in the meantime.

Every time you find yourself adding a ROS dependency to stage-packages, it means you’re missing that dependency in the package.xml of whatever package depends upon it.

The Catkin plugin doesn’t pull anything other than roslib and roscore by default (the latter can be disabled by the include-roscore option). Every other ROS dependency is resolved using rosdep. If you don’t specify, say, a rundep on actionlib, it won’t be fetched.

You can of course fix it with stage-packages, as you’ve done, but this is an issue I strongly suggest you solve using ROS’s faculties and best practices. It makes your ROS packages more portable.

That’s an excellent explanation, thank you. We tried adding actionlib to our packages.xml and saw no change. We had it specified as both run and build dependency. Since we’re still seeing that the rosdep view is empty error and rosdep is responsible for fetching, could it be that these issues are related?

Not unless you’re seeing the “view is empty” error during build-time.

Note that fetching rosdep dependencies is done as part of the pull step. Did you clean before running again (snapcraft isn’t quite smart enough to know you changed stuff, yet)?

Thanks again, that was one of the many tricks to getting us closer to working. I saw that you recently added support for building pip dependencies but can’t quite make sense of how to use it. Do you have an example somewhere?

Totally! You can just take a look at the integration test snap we use to ensure it continues to work, here. However, it’s really no different than any other rosdep dependency: you specify it in the package.xml, and if it resolves to a pip dependency, the Catkin plugin will fetch it for you exactly like it does debs.

We are in business! The same rosdep view is empty message is there but it’s not hurting anything. I successfully added another part dependencies from our Git repo, swapped out one of the apt-provided ROS packages for our fork that includes a bugfix, and shuffled around some Python dependencies to get it all working. I’m now going to document all the changes that were required to our package dependencies, check our snapcraft.yaml into git, wipe, and start over. We haven’t had to deal with that kernel module yet and there’s still more to do before I move to Ubuntu Core, but this is a huge step. Thanks for your help so far. I’ll email you some notes when everything’s all cleaned up.

Hey, awesome! Congratulations, you learned a lot very quickly :grin: !

I look forward to your notes. Until then, you know where you find me if you have any more issues!

Well it sort of helps when you’ve got THE EXPERT feeding you answers. :joy: