#singularity-container
#сингулярность-контейнер
Вопрос:
Я новичок в Singularity.
Чего я хочу достичь в долгосрочной перспективе: у меня есть программный проект с длинными списками зависимостей, и я хочу иметь возможность предоставлять программу другим людям в моей компании без ошибок, вызванных отсутствующими зависимостями или неправильными версиями зависимостей.
Идея заключалась в том, чтобы теперь использовать Singularity, чтобы легко обеспечить рабочую среду.
Чтобы протестировать это, я написал приложение Hello World, которое теперь хочу запустить в контейнере. У меня есть папка HelloWorld/
, которая содержит исходный код для проекта C Qt. Затем я написал следующий файл рецепта:
project.recipe
Bootstrap: docker
From: ubuntu:18.04
%setup
cp -R <some_folder>/HelloWorld ${SINGULARITY_ROOTFS}/HelloWorld
%post
apt update
apt-get install -y qt5-default
apt install -y g
apt-get install -y build-essential
cd HelloWorld
qmake
make
echo "after build:"
ls
%runscript
echo "before execution:"
ls HelloWorld/
./HelloWorld/HelloWorld
где находятся эхо-сигналы и списки каталогов для моего текущего процесса отладки.
Я могу успешно создать файл изображения с помощью sudo singularity build --writable project.img project.recipe
. (Мои выходные данные отладки показывают мне, что исполняемый файл был собран успешно.)
Проблема теперь в том, что если я попытаюсь запустить его с помощью ./project.img
или singularity run project.img
, он не найдет исполняемый файл.
Используя мои выходные данные отладки, я обнаружил, что строки в %runscript
используют папки за пределами контейнера.
Учебные пособия, подобные https://sylabs.io/guides/3.1/user-guide/build_a_container.html мне показалось, что мой рецепт — это правильный путь, но, по-видимому, это не так?
Мои вопросы:
- Есть ли какой-нибудь способ для меня получить доступ к моему исполняемому файлу? Я неправильно это называю?
- Является ли то, как я это делаю, тем, как это должно быть сделано? Или обычно нужно сделать что-то вроде получения исполняемого файла вне контейнера, а затем использовать контейнер для вызова этого внешнего файла? Или есть другая лучшая практика?
- Если исполняемый файл должен быть скопирован за пределы контейнера после компиляции, как мне это сделать? Как мне получить доступ к внешним папкам, когда я внутри
%post
? - Является ли это лучшим рабочим процессом для того, чего я хочу достичь? Позже моя идея заключается в том, что большой проект копируется аналогичным образом в контейнер, зависимости либо устанавливаются, либо копируются, затем проект компилируется и, наконец, его исходный код удаляется. Я также рассматривал возможность использования репозитория, но я не могу разместить проект в открытом репозитории, и я не хочу хранить какие-либо пароли.
Ответ №1:
- Во-первых, используйте
%files
, не используйте%setup
.%setup
запускается от имени root и может напрямую изменять хост-сервер. Вы можете очень легко и случайно что-то сломать, не осознавая этого. Таким образом, вы можете получить тот же эффект:
%files
some_folder/HelloWorld /HelloWorld
-
Вы называете это неправильно. На ваших
%setup
(и, надеюсь, теперь на ваших%files
) шагах вы копируете данные в/HelloWorld
. В вашем%runscript
вызывается./HelloWorld/HelloWorld
, что эквивалентно$PWD/HelloWorld/HelloWorld
. Поскольку singularity автоматически монтируется в$PWD
(а также$HOME
и некоторых других каталогах), вы вызываете не то, что пытаетесь вызвать. -
Вы не копируете исполняемый файл за пределы контейнера, вам просто нужно убедиться, что то, что вы выполняете, находится там, где вы думаете, что это.
-
В
%post
нет доступа к файловой системе хоста, сначала вы должны скопировать все, что вам нужно, в via%files
. -
Это разумный рабочий процесс. Наличие локального частного репозитория для кода, вероятно, является хорошей идеей для отслеживания ваших изменений, но это ваш выбор.
Комментарии:
1. Ах, мне просто нужно было убрать точку. Спасибо. Для меня это звучит нелогично. Что касается папки, я сделал это, потому что прочитал, что %files не будет работать с папками, но я сделал, как вы сказали, и это работает — это несколько новая функция?
2. Что касается пункта 4., как бы вы это сделали, не сохраняя открыто пароль в рецепте? Или мы скорее говорим о рабочем процессе вне контейнера?