1 # Configurations that should only be overrided by
6 , projectName # "apptainer" or "singularity"
10 , extraConfigureFlags ? [ ]
11 , extraDescription ? ""
16 # Workaround for vendor-related attributes not overridable (#86349)
17 # should be removed when the issue is resolved
18 _defaultGoVendorArgs = {
43 , fuse2fs ? e2fsprogs.fuse2fs
48 # This is for nvidia-container-cli
57 # Overridable configurations
58 , enableNvidiaContainerCli ? true
59 # --nvccli currently requires extra privileges:
60 # https://github.com/apptainer/apptainer/issues/1893#issuecomment-1881240800
62 # Compile with seccomp support
63 # SingularityCE 3.10.0 and above requires explicit --without-seccomp when libseccomp is not available.
64 , enableSeccomp ? true
65 # Whether the configure script treat SUID support as default
66 # When equal to enableSuid, it supress the --with-suid / --without-suid build flag
67 # It can be set to `null` to always pass either --with-suid or --without-suided
68 # Type: null or boolean
69 , defaultToSuid ? true
70 # Whether to compile with SUID support
72 , starterSuidPath ? null
74 # newuidmapPath and newgidmapPath are to support --fakeroot
75 # where those SUID-ed executables are unavailable from the FHS system PATH.
76 # Path to SUID-ed newuidmap executable
77 , newuidmapPath ? null
78 # Path to SUID-ed newgidmap executable
79 , newgidmapPath ? null
80 # External LOCALSTATEDIR
81 , externalLocalStateDir ? null
82 # Remove the symlinks to `singularity*` when projectName != "singularity"
83 , removeCompat ? false
85 # should be removed when the issue is resolved
86 , vendorHash ? _defaultGoVendorArgs.vendorHash
87 , deleteVendor ? _defaultGoVendorArgs.deleteVendor
88 , proxyVendor ? _defaultGoVendorArgs.proxyVendor
92 defaultPathOriginal = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin";
93 privileged-un-utils = if ((newuidmapPath == null) && (newgidmapPath == null)) then null else
94 (runCommandLocal "privileged-un-utils" { } ''
96 ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap"
97 ln -s ${lib.escapeShellArg newgidmapPath} "$out/bin/newgidmap"
101 inherit pname version src;
103 patches = lib.optionals (projectName == "apptainer") [
104 (substituteAll { src = ./apptainer/0001-ldCache-patch-for-driverLink.patch; inherit (addDriverRunpath) driverLink; })
107 # Override vendorHash with the output got from
108 # nix-prefetch -E "{ sha256 }: ((import ./. { }).apptainer.override { vendorHash = sha256; }).goModules"
109 # or with `null` when using vendored source tarball.
110 inherit vendorHash deleteVendor proxyVendor;
112 # go is used to compile extensions when building container images
113 allowGoReference = true;
121 externalLocalStateDir
128 nativeBuildInputs = [
135 # Search inside the project sources
136 # and see the `control` file of the Debian package from upstream repos
137 # for build-time dependencies and run-time utilities
138 # apptainer/apptainer: https://github.com/apptainer/apptainer/blob/main/dist/debian/control
139 # sylabs/singularity: https://github.com/sylabs/singularity/blob/main/debian/control
142 bash # To patch /bin/sh shebangs.
148 squashfsTools # Required at build time by SingularityCE
150 ++ lib.optional enableNvidiaContainerCli nvidia-docker
151 ++ lib.optional enableSeccomp libseccomp
154 configureScript = "./mconfig";
157 "--localstatedir=${if externalLocalStateDir != null then externalLocalStateDir else "${placeholder "out"}/var/lib"}"
158 "--runstatedir=/var/run"
160 ++ lib.optional (!enableSeccomp) "--without-seccomp"
161 ++ lib.optional (enableSuid != defaultToSuid) (if enableSuid then "--with-suid" else "--without-suid")
162 ++ extraConfigureFlags
165 # causes redefinition of _FORTIFY_SOURCE
166 hardeningDisable = [ "fortify3" ];
168 # Packages to prefix to the Apptainer/Singularity container runtime default PATH
169 # Use overrideAttrs to override
170 defaultPathInputs = [
173 cryptsetup # cryptsetup
175 fuse2fs # Mount ext3 filesystems
178 squashfsTools # mksquashfs unsquashfs # Make / unpack squashfs image
179 squashfuse # squashfuse_ll squashfuse # Mount (without unpacking) a squashfs image without privileges
181 ++ lib.optional enableNvidiaContainerCli nvidia-docker
185 if [[ ! -e .git || ! -e VERSION ]]; then
186 echo "${version}" > VERSION
189 # Patch shebangs for script run during build
190 patchShebangs --build "$configureScript" makeit e2e scripts mlocal/scripts
192 # Patching the hard-coded defaultPath by prefixing the packages in defaultPathInputs
193 substituteInPlace cmd/internal/cli/actions.go \
194 --replace "defaultPath = \"${defaultPathOriginal}\"" "defaultPath = \"''${defaultPathInputs// /\/bin:}''${defaultPathInputs:+/bin:}${defaultPathOriginal}\""
196 substituteInPlace internal/pkg/util/gpu/nvidia.go \
198 'return fmt.Errorf("/usr/bin not writable in the container")' \
203 # Code borrowed from pkgs/stdenv/generic/setup.sh configurePhase()
205 # set to empty if unset
206 : ''${configureFlags=}
208 # shellcheck disable=SC2086
209 $configureScript -V ${version} "''${prefixKey:---prefix=}$prefix" $configureFlags "''${configureFlagsArray[@]}"
211 # End of the code from pkgs/stdenv/generic/setup.sh configurPhase()
216 make -C builddir -j"$NIX_BUILD_CORES"
222 make -C builddir install LOCALSTATEDIR="$out/var/lib"
227 substituteInPlace "$out/bin/run-singularity" \
228 --replace "/usr/bin/env ${projectName}" "$out/bin/${projectName}"
229 wrapProgram "$out/bin/${projectName}" \
230 --prefix PATH : "''${defaultPathInputs// /\/bin:}''${defaultPathInputs:+/bin:}"
231 # Make changes in the config file
232 ${lib.optionalString forceNvcCli ''
233 substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \
234 --replace "use nvidia-container-cli = no" "use nvidia-container-cli = yes"
236 ${lib.optionalString (enableNvidiaContainerCli && projectName == "singularity") ''
237 substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \
238 --replace "# nvidia-container-cli path =" "nvidia-container-cli path = ${nvidia-docker}/bin/nvidia-container-cli"
240 ${lib.optionalString (removeCompat && (projectName != "singularity")) ''
241 unlink "$out/bin/singularity"
242 for file in "$out"/share/man/man?/singularity*.gz; do
243 if [[ -L "$file" ]]; then
247 for file in "$out"/share/*-completion/completions/singularity; do
252 ${lib.optionalString enableSuid (lib.warnIf (starterSuidPath == null) "${projectName}: Null starterSuidPath when enableSuid produces non-SUID-ed starter-suid and run-time permission denial." ''
253 chmod +x $out/libexec/${projectName}/bin/starter-suid
255 ${lib.optionalString (enableSuid && (starterSuidPath != null)) ''
256 mv "$out"/libexec/${projectName}/bin/starter-suid{,.orig}
257 ln -s ${lib.escapeShellArg starterSuidPath} "$out/libexec/${projectName}/bin/starter-suid"
262 description = "Application containers for linux" + extraDescription;
264 Singularity (the upstream) renamed themselves to Apptainer
265 to distinguish themselves from a fork made by Sylabs Inc.. See
267 https://sylabs.io/2021/05/singularity-community-edition
268 https://apptainer.org/news/community-announcement-20211130
270 license = licenses.bsd3;
271 platforms = platforms.linux;
272 maintainers = with maintainers; [ jbedo ShamrockLee ];
273 mainProgram = projectName;
275 }).overrideAttrs (finalAttrs: prevAttrs: {
276 passthru = prevAttrs.passthru or { } // {
278 image-hello-cowsay = singularity-tools.buildImage {
279 name = "hello-cowsay";
280 contents = [ hello cowsay ];
281 singularity = finalAttrs.finalPackage;
284 gpuChecks = lib.optionalAttrs (projectName == "apptainer") {
285 # Should be in tests, but Ofborg would skip image-hello-cowsay because
287 image-saxpy = callPackage
288 ({ singularity-tools, cudaPackages }:
289 singularity-tools.buildImage {
291 contents = [ cudaPackages.saxpy ];
294 singularity = finalAttrs.finalPackage;
299 ({ runCommand, writeShellScriptBin }:
301 unwrapped = writeShellScriptBin "apptainer-cuda-saxpy"
303 ${lib.getExe finalAttrs.finalPackage} exec --nv $@ ${finalAttrs.passthru.gpuChecks.image-saxpy} saxpy
306 runCommand "run-apptainer-cuda-saxpy"
308 requiredSystemFeatures = [ "cuda" ];
309 nativeBuildInputs = [ unwrapped ];
310 passthru = { inherit unwrapped; };