Как мне на самом деле вызывать произвольные двоичные файлы и получать доступ к файловой системе из пакета, созданного с помощью Snap?

Вопрос или проблема

Никакие из рекомендаций и других ответов на самом деле не работают! Итак, я установил 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-печати. Точный контент макроса не важен, но важно, что он делает две вещи:

  1. Создает файл STL из выбранного твердого тела и сохраняет его в /tmp
  2. Вызывает слайсер (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. Однако вы можете попробовать создать исполняемый файл и установить ему нужный путь:

  1. Создайте файл cura.sh в каталоге ~/snap/freecad/common/:
#!/bin/sh
flatpak run com.ultimaker.cura "$@"
  1. Убедитесь, что файл исполняемый:
chmod +x ~/snap/freecad/common/cura.sh
  1. Теперь измените вашу команду в макросе на:
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 для более углубленной помощи.

Оцените материал
Добавить комментарий

Капча загружается...