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
The bin/remarkable
file in your git repository begins with:
#! /usr/bin/python3
But the snapcraft.yaml
file shows it being invoked with a Python interpreter that is shipped within your snap:
apps:
remarkable-deadolus:
command: usr/bin/python3 $SNAP/bin/remarkable
The two interpreters have different import paths, so the parent and child processes can see different sets of Python modules.
One solution is to change how you launch the subprocess. The sys.executable
variable holds the path to the currently running Python interpreter, so you could try changing the Popen call to:
subprocess.Popen([sys.executable, sys.argv[0]])