Confine python popen child to snap container

I try to confing a python subprocess.Popen process to a snap package I built.

To learn about snap package creation I decided to build a snap container for a markdown editor, built in python, I regularly use. I managed to create a snapcraft.yaml file, which I am able to install and start the editor with successfully.

However, the editor allows the user to open a second window, e.g. to edit a second file. Internally it calls subprocess.Popen(sys.argv[0]), so it creates a child process of itself.
I fail to confine this new process to the snap itself.
argv0 on both parent and child is set to /snap/remarkable-deadolus/x34/bin/remarkable, which I verified by creating some debug output.

The new process fails to find some libraries, which apparently were successfully found (because the snap package installed them) by the main process:

Traceback (most recent call last):
  File "/snap/remarkable-deadolus/x34/bin/remarkable", line 72, in <module>
    import remarkable
  File "/snap/remarkable-deadolus/x34/remarkable/__init__.py", line 26, in <module>
    import gi
ModuleNotFoundError: No module named 'gi'

When investigating I found that some (environment) variables seem to differ between the creation of the main snap process and its children. The call to print(sys.prefix) in the parent produces /snap/remarkable-deadolus/x33/usr. In the child however it produces /usr.

So my question is how can I confine the child processes of a python snap program to the snap package?

Here is my progress so far: Deadolus Github Remarkable with snapcraft.yaml file

For reference, my commands to build and then run the snap package are:

snapcraft --debug
sudo snap install --devmode *.snap
remarkable-deadolus

In the snapcraft.yaml file I enabled strict confinement by adding

confinement: strict

P.S: I also added this question to StackOverflow: https://stackoverflow.com/questions/58622697/confine-python-popen-child-snap-container

I suspect the initial process is being started outside of confinement. You can see with ps auxwwZ and look for your process. It may say ‘unconfined’. If so, be sure to launch your initial application from /snap/bin.

Also, because you are installing with --devmode, note that policy violations are logged, but allowed.

From the sound of it, your main process is being run with a Python interpreter packaged with your snap, and the subprocess is using the Python interpreter included in the base snap.

You can determine the Python interpreter you’re running under using sys.executable. So maybe try changing your call to subprocess.Popen([sys.executable, sys.argv[0], ...]) instead?

Hi @jdstrand and @jamesh thanks for your inputs!

I checked and it seems to be confined, this is the output I get:

snap.remarkable-deadolus.remarkable-deadolus (complain) user 28406 20.5 0.5 102996848 88340 pts/33 Sl+ 13:52 0:05 /snap/remarkable-deadolus/x35/usr/bin/python3 /snap/remarkable-deadolus/x35/bin/remarkable
snap.remarkable-deadolus.remarkable-deadolus (complain) user 28659 12.4 0.5 103268608 87964 pts/33 SLl+ 13:52 0:02 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess 4 19
snap.remarkable-deadolus.remarkable-deadolus (complain) user 28660 0.7 0.2 86121324 35768 pts/33 SLl+ 13:52 0:00 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess 5 19

Also if I uninstall the snap container (“deadolus-remarkable”) it is not found anymore.
So there is no second command shadowing this snap command.
I use --devmode because the package is not yet signed, so it won’t install without this switch and instead complain about missing signatures.
There also is no further error output than the “no module found” error.

If I change the Popen call according to @jamesh this actually solves the issue.
I still think it is a bit strange, but happy that it now works - thank you both for chipping in.
@jamesh, if you want to add your solution to the SO question I’d be very happy to accept the solution.
Otherwise I’ll add it myself, so that other users might find it more easily in the future.