我正在尝试运行具有 Singularity 的 Docker 容器,该容器通过 Wine 执行 Windows 程序(来自 proteowizard 的 msconvert)。此图片:https://hub.docker.com/r/chambm/pwiz-skyline-i-agree-to-the-vendor-licenses
Docker 容器内的 Wine 安装由 root 所有。在标准用户帐户上使用 Singularity 运行
singularity run --env WINEDEBUG=-all pwiz.sif wine msconvert
结果:
wine: '/wineprefix64' is not owned by you
所以我必须使用
--fakeroot
选项来克服这个问题。
但是,在远程 HPC 系统上我希望运行我无法使用的容器
--fakeroot
,因为系统管理员不允许:
FATAL: while extracting pwiz.sif: root filesystem extraction failed: extract command failed: FATAL: configuration disallows users from running sandbox based containers
我的解决方法是添加
%post
来构建容器并将目录的所有权更改为远程系统的用户,然后在我具有 root 访问权限的计算机上重建 Singularity 映像。简单地说:
Bootstrap: docker
From: chambm/pwiz-skyline-i-agree-to-the-vendor-licenses
%post
useradd -u 1234 user
chown -Rf --no-preserve-root user /wineprefix64
这对我有用。但我的问题是,是否有更好的方法来概括这一点,以便任何非特权用户都可以运行它,而无需为其用户名手动重新构建它?
为了概括该方法,我们可以专注于确保 Singularity 容器设置为允许任何用户运行它,而无需进行特定的所有权修改。
通用方法:
为每个用户创建一个可写的 Wine 前缀:
修改 Singularity 定义文件以创建和使用用户特定的 Wine 前缀:
以下是修改奇点定义文件的方法:
Bootstrap: docker
From: chambm/pwiz-skyline-i-agree-to-the-vendor-licenses
%post
# Install necessary packages and add user (as you did)
useradd -u 1234 user
mkdir -p /wineprefix_template
wine64 wineboot --init # Initialize a template Wine prefix
mv ~/.wine/* /wineprefix_template/ # Move it to a template location
%environment
export WINEPREFIX=$HOME/.wineprefix64
%runscript
# Create a Wine prefix in the user's home directory if it doesn't exist
if [ ! -d "$WINEPREFIX" ]; then
mkdir -p $WINEPREFIX
cp -r /wineprefix_template/* $WINEPREFIX/
fi
wine "$@"
%post 部分: - 我们在构建期间初始化 Wine 前缀并将其保存到模板目录
/wineprefix_template
%environment 部分: - 我们将
WINEPREFIX
环境变量设置为用户特定的目录,$HOME/.wineprefix64
%runscript 部分: - 当容器运行时,它会检查用户主目录中是否存在
WINEPREFIX
目录。如果没有,它会创建目录并将模板 Wine 前缀复制到此位置。这确保每个用户都有自己的可写 Wine 前缀。
用途:
当用户使用 Singularity 运行容器时,
%runscript
部分中的脚本将在其主目录中创建自己的 Wine 前缀(如果尚不存在),确保 Wine 可以写入此目录,而无需 root 权限或特定权限用户所有权发生变化。
singularity run --env WINEDEBUG=-all pwiz.sif msconvert
这种方法确保容器可以被任何用户使用,而无需为每个特定用户重新构建,从而使其在共享 HPC 环境中更加灵活和用户友好。