Request classic confinement for tesseract-ignition

Hello,

I seeking approval for tesseract-ignition setup wizard. This is a ROS developers tool that supports the creation of a semantic robot description file. ROS is typically installed in the /opt/ros directory so I believe classic confinement is required to ready file from this location. In addition I have noticed that my Qt GUI will only work in classic confinement otherwise I get an xcb missing error.

To access paths like /opt/ros, you should be able to use an appropriate system-files. Qt GUI applications should also work fine in general without classic confinement - I see you are already plugging the desktop interface - can you elaborate more on the errors which you see? Perhaps you need to ensure you include xcb within the snap itself - in which case I suggest you look into using stage-packages.

As such, based on the above classic confinement does not appear to be required for tesseract-ignition from what I can see.

Actually, /opt/ros won’t be in the runtime environment of the snap (recall that snaps’ mount namespace consists of base snap that constitutes the root fs with a few writable directories on top (eg, /etc, /home, etc, but not /opt), so system-files cannot be used for this at present. A layout could be used for /opt/ros though. system-files could be used for hostfs (/var/lib/snapd/hostfs/opt/ros), but if changing the paths for that, could just change the paths to point into the snap. @kyrofa - as someone who has worked with ROS and snaps extensively, can you comment and perhaps give a path forward?

As for the xcb missing error, you are likely simply missing something from ‘stage-packages’. Looking at the chromium snap, I see it is staging (among other things) libgl1-mesa-glx, which will pull in libglx-mesa0, which pulls in various libxcb packages (you will probably want to plugs the opengl interface as well if you aren’t already).

I will try without classic again and post the actual error along with trying some of the proposed changes. Here is the current snapcraft.yaml file I have.

When I switch to strict confinement I get the error below. I have tried several things but I have not been able to resolve the issue.

This application failed to start because it could not find or load the Qt platform plugin “xcb”
in “”.

@galgalesh and/or @lucyllewy does this look familiar to you?

typically xcb suport comes with the qt desktop launcher (along with font setup. themes and other essential bits) … seems this app doesnt use it ?

1 Like

I’ve seen similar - the desktop-helper parts usually alleviate the issue (the snapcraft.yaml linked above doesn’t use the desktop-helpers or any snapcraft extensions). I think it’s something missing in the environment, either environment variable settings or a missing stage-package, or both.

1 Like

So I switched to using the kde-neon extension pushed by changes. I now get the following error. Any ides what the issue might be? Everything works with classic confinement but with strict I get the error below; why would the confinement in this case cause an issue?

larmstrong@swri:~/catkin_ws/aris_ws/src/opw_kinematics$ tesseract-ignition.tesseract-setup-wizard 
Qt: Session management error: None of the authentication protocols specified are supported
[Dbg] [Application.cc:87] Initializing application.
[GUI] [Dbg] [Application.cc:407] Create main window
[GUI] [Wrn] [Application.cc:649] [QT] QQmlApplicationEngine failed to load component
[GUI] [Wrn] [Application.cc:649] [QT] qrc:qml/Main.qml:18 plugin cannot be loaded for module "QtQuick.Controls": Failed to extract plugin meta data from '/snap/tesseract-ignition/x16/kf5/usr/lib/x86_64-linux-gnu/qt5/qml/QtQuick/Controls.2/libqtquickcontrols2plugin.so'

Ok, so I was able to get more information about what the issues by passing in the QT_DEBUG_PLUGINS environment variable. I was missing some stage-packages, though not sure why it worked in classic.

QT_DEBUG_PLUGINS=1 tesseract-ignition.tesseract-setup-wizard

The only thing now is I need to know how to provide access to the host machine /opt/ros directory? I tried the process below using system-files but it does not appear to work.

plugs:
  ros-plug:
    interface: system-files
    read: [/opt/ros]
apps:
  tesseract-setup-wizard:
    extensions:
        - kde-neon
    plugs:
        - desktop
        - desktop-legacy
        - wayland
        - x11
        - home
        - network
        - opengl
        - ros-plug
    environment:
      IGN_GUI_PLUGIN_PATH: $SNAP/opt/ros/melodic/lib/
      IGN_RENDERING_PLUGIN_PATH: $SNAP/opt/ros/melodic/lib/
      IGN_RENDERING_RESOURCE_PATH: $SNAP/opt/ros/melodic/share/ignition/ignition-rendering4/
      OGRE_RESOURCE_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/OGRE-1.9.0/
      TSW_CONFIG_PATH: $SNAP/opt/ros/melodic/share/tesseract_ignition/config/setup_wizard.config
    command: bin/desktop-launch $SNAP/opt/ros/melodic/bin/tesseract_setup_wizard_app

@jdstrand When using layout would it map the host machine /opt/ros to the snap /opt/ros?

No, layouts are for making files from inside your snap snap appear at a given system location within the snap’s runtime environment. Technically speaking, you could potentially try a system-files interface access for for /var/lib/snapd/hostfs/opt/ros, and then use a layout for

layout:
  /opt/ros:
    bind: /var/lib/snapd/hostfs/opt/ros

however that is disallowed by layouts, see the docs:

<source-path> must refer to either $SNAP , $SNAP_DATA or $SNAP_USER_DATA .

I’m not sure if that is disallowed for a technical reason or a policy decision to specifically prevent mapping things from the host inside the snap’s mount namespace as that would be an information leak of the host to the snap (but maybe an interface could allow specific directories from the host like this).

So does this mean I need to release this with classic confinement to gain access to the host machines /opt/ros directory?

I continue to want to hear from @kyrofa on this point as a snap store reviewer and ROS snap developer/advocate/guru.

1 Like

Sorry for the delay folks, I was out of the office for a week or so and I’m still catching up on things.

My understanding of the application (@Levi-Armstrong please jump in to correct me if I’m wrong) is that the user is presented with a list of discovered 3D meshes which can be imported into the tool. Some of these meshes are shipped in tesseract itself, but the user can also have their own installed, in which case they will most likely be contained in /opt/ros on the host. To be clear, tesseract does not own /opt/ros, but then again, nothing really does-- that’s just where ROS workspaces are conventionally installed (e.g. all upstream ROS components gets installed there). In many cases for a ROS snap, the snap is self-sufficient and it doesn’t make sense for it to care if ROS is installed on the host. Even if it did, if it tried to load a library from there it would probably fail as it wouldn’t be able to link to other libs. In this case, this snap is a utility that operates on a given ROS workspace and only loads meshes out of it, so this seems to make sense to me.

ROS is typically installed in the /opt/ros directory so I believe classic confinement is required to ready file from this location.

I am hoping that isn’t the case. I pointed @Levi-Armstrong at system-files, but neglected to account for the fact that /opt/ros/ would actually be in /var/lib/snapd/hostfs/opt/ros/. This means the environment variables defined by ROS that make it possible to find it will be pointing to the wrong place in the snap. We can work around that, but it’s kind of ugly. Let’s cross that bridge when we get to it though, and start with system-files.

@Levi-Armstrong, your snapcraft.yaml is close, but you need to change the read item to use /var/lib/snapd/hostfs/opt/ros as opposed to just /opt/ros. You’ll probably need a better name as well, but we can deal with that later.

As soon as you build and install that snap, you need to connect the interface (sudo snap connect tesseract-ignition:ros-plug), and then the snap will be able to access the host’s /opt/ros by visiting /var/lib/snapd/hostfs/opt/ros. Make sense?

Once we get there, we can deal with remapping the host’s ROS_PACKAGE_PATH into /var/lib/snapd/hostfs/opt/ros. Also, now that we’re here, does tesseract actually support multiple ROS releases? Or should that interface actually be for a specific subdirectory of /opt/ros/?

This is correct, I will not be linking. Only need access to load 3d meshes stored in various packages located in /opt/ros/.

I am adding the updated path now and rebuilding. Once finished I will test and confirm that I see my host machines files in the path /var/lib/snapd/hostfs/opt/ros.

It does. It actually does not use anything of ros other than the catkin build tool. I will parse the environment variable [ROS_PACKAGE_PATH and TSW_RESOURCE_PATH] to get location of package directories. It creates a map of package names to install locations so when it parses the urdf it can replace <mesh filename="package://tesseract_support/urdf/lbr_iiwa_14_r820/collision/link_7.stl"/> the package://tesseract_support with the path to package tesseract_support.

1 Like

I updated the snapcraft.yaml but not sure if it worked. Below are the steps I went through once it was built. I expect when my app launched that I could browse to the location provided in the system-files but nothing is in the var directory. Any thoughts?

Steps followed

snap install --dangerous tesseract-ignition_0.5_amd64.snap
snap connect tesseract-ignition:ros-plug
tesseract-ignition.tesseract-setup-wizard

image

You may not be able to do that under confinement. Try this:

$ sudo snap run --shell tesseract-ignition.tesseract-setup-wizard -c 'ls -l /var/lib/snapd/hostfs/opt/ros`

snap run --shell allows you to run bash under the same confinement profile as your app. In this case, we use -c to do the ls. If that works, then the plug is working.

I get the error below.

mkdir: cannot create directory ‘/run/user/0’: Permission denied
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
realpath: '': No such file or directory
ls: cannot open directory '/var/lib/snapd/hostfs/opt/ros': Permission denied

Can you confirm that you actually connected that interface (it’s not connected by default)? Here’s a minimum reproducer:

name: my-snap-name # you probably want to 'snapcraft register <name>'
base: core18 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: strict

plugs:
  opt-ros:
    interface: system-files
    read:
      - /var/lib/snapd/hostfs/opt/ros

parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: nil

apps:
  foo:
    command: ls /var/lib/snapd/hostfs/opt/ros
    plugs: [opt-ros]

Once you build that, install it:

$ sudo snap install my-snap-name_0.1_amd64.snap --dangerous

At this point, you’ll see the permission denied like what you saw:

$ my-snap-name.foo 
/bin/ls: cannot open directory '/var/lib/snapd/hostfs/opt/ros': Permission denied

That’s because the interface plug isn’t connected to a slot:

$ snap connections my-snap-name 
Interface     Plug                  Slot  Notes
system-files  my-snap-name:opt-ros  -     -

Once we connect it:

$ sudo snap connect my-snap-name:opt-ros

Things work as expected:

$ my-snap-name.foo 
melodic

Can you duplicate those results using my example on your system?