Вопрос или проблема
Никакие из рекомендаций и других ответов на самом деле не работают! Итак, я установил FreeCAD через Snap, так как в нем есть последние релиз-кандидаты и он предоставляет более удобный интерфейс, чем AppImage. Мне также нравится, что Snap интегрирован в Центр установки, в то время как AppImage – это просто бинарный файл где-то в моей файловой системе, о котором я сразу забываю.
sudo snap install freecad --devmode --channel=candidate
Обратите внимание, что я не могу установить его в classic
режиме (--classic
), потому что он не собран с этим режимом:
Warning: flag --classic ignored for strictly confined snap freecad
Проверка установки devmode
:
$ sudo snap info --verbose freecad
…
notes:
private: false
confinement: strict
devmode: true
jailmode: false
trymode: false
enabled: true
broken: false
ignore-validation: false
…
Итак, у него strict
режим ограничения, согласно snapcraft.yml
, но установлен в devmode
, который, согласно документации…
Особый режим для создателей и разработчиков snap. Snap в
devmode
работает как строго ограниченный snap с полным доступом к системным ресурсам и производит отладочный вывод для выявления неопределенных интерфейсов. Установка требует аргумент командной строки –devmode. Snap в режиме devmode не может быть выпущен в стабильный канал, не появляется в результатах поиска и не обновляется автоматически.
Вот что мне нужно, потому что в FreeCAD у меня есть макрос для нарезки твердого тела в слайсер для 3D-печати. Точный контент макроса не важен, но важно, что он делает две вещи:
- Создает файл STL из выбранного твердого тела и сохраняет его в
/tmp
- Вызывает слайсер (Cura) с путём к тому STL из предыдущего шага.
Вот фрагмент кода для 1:
file = f'/tmp/{mesh.Label}_{id}.stl'
print(f'Экспортируем {selected.Label} в {file}')
Mesh.export([mesh], file)
А вот и 2:
subprocess.Popen(['/usr/bin/flatpak', 'run', 'com.ultimaker.cura', file])
Да, Cura установлена из Flathub, но в общем flatpak run com.ultimaker.cura
работает в моем терминале.
Выполнение макроса вызывает ошибку:
17:20:02 Экспортируем Cube в /tmp/Cube001_618c394b-5e90-4af2-9e57-8fae23708f9c.stl
17:20:02 pyException: Traceback (most recent call last):
File "/home/siarhei_krukau/snap/freecad/common/Cura.FCMacro", line 31, in <module>
subprocess.Popen(['/usr/bin/flatpak', 'run', 'com.ultimaker.cura', *files])
File "/snap/freecad/1154/usr/lib/python3.10/subprocess.py", line 971, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/snap/freecad/1154/usr/lib/python3.10/subprocess.py", line 1863, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
<class 'FileNotFoundError'>: [Errno 2] Нет такого файла или каталога: '/usr/bin/flatpak'
Сначала, хотя и сказано “Экспортируем Cube в /tmp/Cube001_618c394b-5e90-4af2-9e57-8fae23708f9c.stl”, файла там нет. Вместо этого он находится здесь: /tmp/snap-private-tmp/snap.freecad/tmp/Cube001_618c394b-5e90-4af2-9e57-8fae23708f9c.stl
. Это “частный” /tmp
для snap FreeCAD. Очевидно, что Cura не сможет получить к нему доступ, но я мог бы, вероятно, обойти это и сохранить STL в директории домашнего каталога.
Однако оказывается, что FreeCAD не может “увидеть” исполняемый файл flatpak
из /usr/bin
. Ни из /bin
, ни просто flatpak
— я также пробовал эти варианты. Чтобы быстро проверить “вид” FreeCAD на файловую систему, я выполняю это в его Python-консоли:
>>> [f for f in os.listdir('/usr/bin') if f.startswith('fl')]
['flock']
Тем не менее, тот же код в терминале дает это:
>>> [f for f in os.listdir('/usr/bin') if f.startswith('fl')]
['flock', 'flatpak']
Я также попробовал трюк с созданием небольшого shell-скрипта в common
директории snap (~/snap/freecad/common/cura.sh
), чтобы вместо этого вызвать Cura, и вызывать этот скрипт из макроса:
flatpak run com.ultimaker.cura "$@"
Это тоже не сработало. Та же проблема.
Таким образом, оказывается, что ни FreeCAD не имеет доступа к директории /tmp
, ни к исполнителям в /usr/bin
, /bin
, несмотря на то, что он установлен в devmode
.
Я не ожидал такого от devmode
. Как мне действительно избавиться от этих ограничений?
Ответ или решение
Чтобы решить вашу проблему с доступом к файловой системе и вызовом произвольных бинарных файлов из пакета, установленного через Snap, необходимо учитывать некоторые ключевые моменты, связанные с конфиденциальностью и доступом в Snap-пакетах.
1. Понимание ограничений Snap
Snap-пакеты работают в строго контролируемой среде с ограниченным доступом к системе. Хотя вы установили Snap FreeCAD в режиме devmode
, это не снимает всех ограничений, связанных с доступом к встроенным файловым системам и исполняемым файлам. В режиме devmode
приложение имеет больший доступ к системным ресурсам, но все равно ограничивается изолированным окружением.
2. Решение проблемы с доступом к файловой системе
Для того чтобы FreeCAD мог корректно сохранять сгенерированные файлы (например, STL) в домашней директории, вам нужно изменить путь сохранения в вашем макросе. Вместо того чтобы сохранять файлы в /tmp
, вы можете использовать путь к вашему домашнему каталогу:
file = f'{os.path.expanduser("~")}/Cube001_{id}.stl'
Это обеспечит доступ к файлу позже.
3. Вызов исполняемых файлов
Доступ к исполняемым файлам, установленным вне Snap-пакета, может быть ограничен. Вам нужно убедиться, что вызываемая вами команда доступна для Snap-окружения. Один из способов обойти это — использовать интерфейсы Snap. В данном случае, вещь, которую вы можете попробовать, — это использовать интерфейс home
и включить его при установке вашего Snap-контейнера:
sudo snap connect freecad:home
Этот интерфейс позволит вашему приложению иметь доступ к вашему домашнему каталогу, где находится flatpak
.
4. Создание скрипта для вызова Cura
Создание оболочечного скрипта в директории common
не всегда будет работать из-за контекста, в котором работает Snap. Однако вы можете попробовать создать исполняемый файл и установить ему нужный путь:
- Создайте файл
cura.sh
в каталоге~/snap/freecad/common/
:
#!/bin/sh
flatpak run com.ultimaker.cura "$@"
- Убедитесь, что файл исполняемый:
chmod +x ~/snap/freecad/common/cura.sh
- Теперь измените вашу команду в макросе на:
subprocess.Popen([f'{os.path.expanduser("~")}/snap/freecad/common/cura.sh', file])
5. Проверка разрешений
Убедитесь, что ваша snap-установка FreeCAD включает необходимые интерфейсы с помощью следующей команды:
sudo snap info freecad
Посмотрите на доступные интерфейсы и убедитесь, что у вас имеются активные интерфейсы home
, removable-media
, и другие необходимые.
Заключение
С учетом вышеописанных шагов, вы сможете настроить FreeCAD так, чтобы он мог сохранять файлы в вашем домашнем каталоге и вызывать Cura через вызов оболочки. Если у вас остаются проблемы, возможно, стоит обратиться к сообществу Snap или разработчикам FreeCAD для более углубленной помощи.