211 lines
8.1 KiB
Python
211 lines
8.1 KiB
Python
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
|
#
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
|
|
import os
|
|
import shutil
|
|
|
|
import llnl.util.tty as tty
|
|
|
|
from spack.package import *
|
|
|
|
|
|
class SingularityBase(MakefilePackage):
|
|
variant("suid", default=True, description="install SUID binary")
|
|
variant("network", default=True, description="install network plugins")
|
|
|
|
depends_on("pkgconfig", type="build")
|
|
depends_on("conmon", type=("build", "run"))
|
|
depends_on("squashfs", type=("build", "run"))
|
|
depends_on("go@1.16:")
|
|
depends_on("uuid")
|
|
depends_on("libgpg-error")
|
|
depends_on("libseccomp")
|
|
depends_on("squashfs", type="run")
|
|
depends_on("git", when="@develop") # mconfig uses it for version info
|
|
depends_on("shadow", type="run", when="@3.3:")
|
|
depends_on("cryptsetup", type=("build", "run"), when="@3.4:")
|
|
|
|
conflicts("platform=darwin", msg="singularity requires a Linux VM on Windows & Mac")
|
|
|
|
# Use these properties to buffer the renaming to Apptainer
|
|
singularity_org = "sylabs"
|
|
singularity_name = "singularity"
|
|
singularity_security_urls = (
|
|
"https://sylabs.io/guides/2.6/admin-guide/security.html",
|
|
"https://sylabs.io/guides/3.2/admin-guide/admin_quickstart.html#singularity-security",
|
|
)
|
|
|
|
# Go has novel ideas about how projects should be organized.
|
|
# We'll point GOPATH at the stage dir, and move the unpacked src
|
|
# tree into the proper subdir in our overridden do_stage below.
|
|
@property
|
|
def gopath(self):
|
|
return self.stage.path
|
|
|
|
@property
|
|
def singularity_gopath_dir(self):
|
|
return join_path(
|
|
self.gopath, "src", "github.com", self.singularity_org, self.singularity_name
|
|
)
|
|
|
|
# Unpack the tarball as usual, then move the src dir into
|
|
# its home within GOPATH.
|
|
def do_stage(self, mirror_only=False):
|
|
super().do_stage(mirror_only)
|
|
if not os.path.exists(self.singularity_gopath_dir):
|
|
# Move the expanded source to its destination
|
|
tty.debug(
|
|
"Moving {0} to {1}".format(self.stage.source_path, self.singularity_gopath_dir)
|
|
)
|
|
shutil.move(self.stage.source_path, self.singularity_gopath_dir)
|
|
|
|
# The build process still needs access to the source path,
|
|
# so create a symlink.
|
|
force_symlink(self.singularity_gopath_dir, self.stage.source_path)
|
|
|
|
# MakefilePackage's stages use this via working_dir()
|
|
@property
|
|
def build_directory(self):
|
|
return self.singularity_gopath_dir
|
|
|
|
# Allow overriding config options
|
|
@property
|
|
def config_options(self):
|
|
# Using conmon from spack
|
|
return ["--without-conmon"]
|
|
|
|
# Hijack the edit stage to run mconfig.
|
|
def edit(self, spec, prefix):
|
|
with working_dir(self.build_directory):
|
|
confstring = "./mconfig --prefix=%s" % prefix
|
|
confstring += " " + " ".join(self.config_options)
|
|
if "~suid" in spec:
|
|
confstring += " --without-suid"
|
|
if "~network" in spec:
|
|
confstring += " --without-network"
|
|
configure = Executable(confstring)
|
|
configure()
|
|
|
|
# Set these for use by MakefilePackage's default build/install methods.
|
|
build_targets = ["-C", "builddir", "parallel=False"]
|
|
install_targets = ["install", "-C", "builddir", "parallel=False"]
|
|
|
|
def setup_build_environment(self, env):
|
|
# Point GOPATH at the top of the staging dir for the build step.
|
|
env.prepend_path("GOPATH", self.gopath)
|
|
|
|
# `singularity` has a fixed path where it will look for
|
|
# mksquashfs. If it lives somewhere else you need to specify the
|
|
# full path in the config file. This bit uses filter_file to edit
|
|
# the config file, uncommenting and setting the mksquashfs path.
|
|
@run_after("install")
|
|
def fix_mksquashfs_path(self):
|
|
prefix = self.spec.prefix
|
|
squash_path = join_path(self.spec["squashfs"].prefix.bin, "mksquashfs")
|
|
filter_file(
|
|
r"^# mksquashfs path =",
|
|
"mksquashfs path = {0}".format(squash_path),
|
|
join_path(prefix.etc, self.singularity_name, self.singularity_name + ".conf"),
|
|
)
|
|
|
|
#
|
|
# Assemble a script that fixes the ownership and permissions of several
|
|
# key files, install it, and tty.warn() the user.
|
|
# HEADSUP: https://github.com/spack/spack/pull/10412.
|
|
#
|
|
def perm_script(self):
|
|
return "spack_perms_fix.sh"
|
|
|
|
def perm_script_tmpl(self):
|
|
return "{0}.j2".format(self.perm_script())
|
|
|
|
def perm_script_path(self):
|
|
return join_path(self.spec.prefix.bin, self.perm_script())
|
|
|
|
def _build_script(self, filename, variable_data):
|
|
with open(filename, "w") as f:
|
|
env = spack.tengine.make_environment(dirs=self.package_dir)
|
|
t = env.get_template(self.perm_script_tmpl())
|
|
f.write(t.render(variable_data))
|
|
|
|
@run_after("install")
|
|
def build_perms_script(self):
|
|
if self.spec.satisfies("+suid"):
|
|
script = self.perm_script_path()
|
|
chown_files = [
|
|
fn.format(self.singularity_name)
|
|
for fn in [
|
|
"libexec/{0}/bin/starter-suid",
|
|
"etc/{0}/{0}.conf",
|
|
"etc/{0}/capability.json",
|
|
"etc/{0}/ecl.toml",
|
|
]
|
|
]
|
|
setuid_files = ["libexec/{0}/bin/starter-suid".format(self.singularity_name)]
|
|
self._build_script(
|
|
script,
|
|
{
|
|
"prefix": self.spec.prefix,
|
|
"chown_files": chown_files,
|
|
"setuid_files": setuid_files,
|
|
},
|
|
)
|
|
chmod = which("chmod")
|
|
chmod("555", script)
|
|
|
|
# Until tty output works better from build steps, this ends up in
|
|
# the build log. See https://github.com/spack/spack/pull/10412.
|
|
@run_after("install")
|
|
def caveats(self):
|
|
if self.spec.satisfies("+suid"):
|
|
tty.warn(
|
|
"""
|
|
For full functionality, you'll need to chown and chmod some files
|
|
after installing the package. This has security implications.
|
|
For details, see:
|
|
{1}
|
|
{2}
|
|
|
|
We've installed a script that will make the necessary changes;
|
|
read through it and then execute it as root (e.g. via sudo).
|
|
|
|
The script is named:
|
|
|
|
{0}
|
|
""".format(
|
|
self.perm_script_path(), *self.singularity_security_urls
|
|
)
|
|
)
|
|
|
|
|
|
class Singularityce(SingularityBase):
|
|
"""Singularity is a container technology focused on building portable
|
|
encapsulated environments to support "Mobility of Compute" For older
|
|
versions of Singularity (pre 3.0) you should use singularity-legacy,
|
|
which has a different install base (Autotools).
|
|
|
|
Needs post-install chmod/chown steps to enable full functionality.
|
|
See package definition or `spack-build-out.txt` build log for details,
|
|
e.g.
|
|
|
|
tail -15 $(spack location -i singularity)/.spack/spack-build-out.txt
|
|
"""
|
|
|
|
homepage = "https://sylabs.io/singularity/"
|
|
url = "https://github.com/sylabs/singularity/releases/download/v3.9.1/singularity-ce-3.9.1.tar.gz"
|
|
git = "https://github.com/sylabs/singularity.git"
|
|
|
|
maintainers("alalazo")
|
|
version("master", branch="master")
|
|
|
|
version("3.11.3", sha256="a77ede063fd115f85f98f82d2e30459b5565db7d098665497bcd684bf8edaec9")
|
|
version("3.10.3", sha256="f87d8e212ce209c5212d6faf253b97a24b5d0b6e6b17b5e58b316cdda27a332f")
|
|
version("3.10.2", sha256="b4f279856ea4bf28a1f34f89320c02b545d6e57d4143679920e1ac4267f540e1")
|
|
version("3.10.1", sha256="e3af12edc0260bc3a3a481459a3a4457de9235025e6b37288da80e3cdc011a7a")
|
|
version("3.10.0", sha256="5e22e6cdad66c331668f6cff4544c83917bb3db90da3cf92403a394c5bf8cc8f")
|
|
version("3.9.9", sha256="1381433d64138c08e93ffacdfb4844e82c2288f1e39a9d2c631a1c4021381f2a")
|
|
version("3.9.1", sha256="1ba3bb1719a420f48e9b0a6afdb5011f6c786d0f107ef272528c632fff9fd153")
|
|
version("3.8.0", sha256="5fa2c0e7ef2b814d8aa170826b833f91e5031a85d85cd1292a234e6c55da1be1")
|