1# Configurations that should only be overrided by
2# overrideAttrs
3{ pname
4, version
5, src
6, projectName # "apptainer" or "singularity"
7, vendorHash ? null
8, deleteVendor ? false
9, proxyVendor ? false
10, extraConfigureFlags ? [ ]
11, extraDescription ? ""
12, extraMeta ? { }
13}:
14
15let
16 # Workaround for vendor-related attributes not overridable (#86349)
17 # should be removed when the issue is resolved
18 _defaultGoVendorArgs = {
19 inherit
20 vendorHash
21 deleteVendor
22 proxyVendor
23 ;
24 };
25in
26{ lib
27, buildGoModule
28, runCommandLocal
29 # Native build inputs
30, makeWrapper
31, pkg-config
32, util-linux
33, which
34 # Build inputs
35, bash
36, conmon
37, coreutils
38, cryptsetup
39, e2fsprogs
40, fakeroot
41, fuse2fs ? e2fsprogs.fuse2fs
42, go
43, gpgme
44, libseccomp
45, libuuid
46 # This is for nvidia-container-cli
47, nvidia-docker
48, openssl
49, squashfsTools
50, squashfuse
51 # Test dependencies
52, singularity-tools
53, cowsay
54, hello
55 # Overridable configurations
56, enableNvidiaContainerCli ? true
57 # Compile with seccomp support
58 # SingularityCE 3.10.0 and above requires explicit --without-seccomp when libseccomp is not available.
59, enableSeccomp ? true
60 # Whether the configure script treat SUID support as default
61 # When equal to enableSuid, it supress the --with-suid / --without-suid build flag
62 # It can be set to `null` to always pass either --with-suid or --without-suided
63 # Type: null or boolean
64, defaultToSuid ? true
65 # Whether to compile with SUID support
66, enableSuid ? false
67, starterSuidPath ? null
68 # newuidmapPath and newgidmapPath are to support --fakeroot
69 # where those SUID-ed executables are unavailable from the FHS system PATH.
70 # Path to SUID-ed newuidmap executable
71, newuidmapPath ? null
72 # Path to SUID-ed newgidmap executable
73, newgidmapPath ? null
74 # Remove the symlinks to `singularity*` when projectName != "singularity"
75, removeCompat ? false
76 # Workaround #86349
77 # should be removed when the issue is resolved
78, vendorHash ? _defaultGoVendorArgs.vendorHash
79, deleteVendor ? _defaultGoVendorArgs.deleteVendor
80, proxyVendor ? _defaultGoVendorArgs.proxyVendor
81}:
82
83let
84 defaultPathOriginal = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin";
85 privileged-un-utils = if ((newuidmapPath == null) && (newgidmapPath == null)) then null else
86 (runCommandLocal "privileged-un-utils" { } ''
87 mkdir -p "$out/bin"
88 ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap"
89 ln -s ${lib.escapeShellArg newgidmapPath} "$out/bin/newgidmap"
90 '');
91in
92(buildGoModule {
93 inherit pname version src;
94
95 # Override vendorHash with the output got from
96 # nix-prefetch -E "{ sha256 }: ((import ./. { }).apptainer.override { vendorHash = sha256; }).goModules"
97 # or with `null` when using vendored source tarball.
98 inherit vendorHash deleteVendor proxyVendor;
99
100 # go is used to compile extensions when building container images
101 allowGoReference = true;
102
103 strictDeps = true;
104
105 passthru = {
106 inherit
107 enableSeccomp
108 enableSuid
109 projectName
110 removeCompat
111 starterSuidPath
112 ;
113 };
114
115 nativeBuildInputs = [
116 makeWrapper
117 pkg-config
118 util-linux
119 which
120 ];
121
122 # Search inside the project sources
123 # and see the `control` file of the Debian package from upstream repos
124 # for build-time dependencies and run-time utilities
125 # apptainer/apptainer: https://github.com/apptainer/apptainer/blob/main/dist/debian/control
126 # sylabs/singularity: https://github.com/sylabs/singularity/blob/main/debian/control
127
128 buildInputs = [
129 bash # To patch /bin/sh shebangs.
130 conmon
131 cryptsetup
132 gpgme
133 libuuid
134 openssl
135 squashfsTools # Required at build time by SingularityCE
136 ]
137 ++ lib.optional enableNvidiaContainerCli nvidia-docker
138 ++ lib.optional enableSeccomp libseccomp
139 ;
140
141 configureScript = "./mconfig";
142
143 configureFlags = [
144 "--localstatedir=/var/lib"
145 "--runstatedir=/var/run"
146 ]
147 ++ lib.optional (!enableSeccomp) "--without-seccomp"
148 ++ lib.optional (enableSuid != defaultToSuid) (if enableSuid then "--with-suid" else "--without-suid")
149 ++ extraConfigureFlags
150 ;
151
152 # causes redefinition of _FORTIFY_SOURCE
153 hardeningDisable = [ "fortify3" ];
154
155 # Packages to prefix to the Apptainer/Singularity container runtime default PATH
156 # Use overrideAttrs to override
157 defaultPathInputs = [
158 bash
159 coreutils
160 cryptsetup # cryptsetup
161 fakeroot
162 fuse2fs # Mount ext3 filesystems
163 go
164 privileged-un-utils
165 squashfsTools # mksquashfs unsquashfs # Make / unpack squashfs image
166 squashfuse # squashfuse_ll squashfuse # Mount (without unpacking) a squashfs image without privileges
167 ]
168 ++ lib.optional enableNvidiaContainerCli nvidia-docker
169 ;
170
171 postPatch = ''
172 if [[ ! -e .git || ! -e VERSION ]]; then
173 echo "${version}" > VERSION
174 fi
175 # Patch shebangs for script run during build
176 patchShebangs --build "$configureScript" makeit e2e scripts mlocal/scripts
177 # Patching the hard-coded defaultPath by prefixing the packages in defaultPathInputs
178 substituteInPlace cmd/internal/cli/actions.go \
179 --replace "defaultPath = \"${defaultPathOriginal}\"" "defaultPath = \"''${defaultPathInputs// /\/bin:}''${defaultPathInputs:+/bin:}${defaultPathOriginal}\""
180 '';
181
182 postConfigure = ''
183 # Code borrowed from pkgs/stdenv/generic/setup.sh configurePhase()
184
185 # set to empty if unset
186 : ''${configureFlags=}
187
188 # shellcheck disable=SC2086
189 $configureScript -V ${version} "''${prefixKey:---prefix=}$prefix" $configureFlags "''${configureFlagsArray[@]}"
190
191 # End of the code from pkgs/stdenv/generic/setup.sh configurPhase()
192 '';
193
194 buildPhase = ''
195 runHook preBuild
196 make -C builddir -j"$NIX_BUILD_CORES"
197 runHook postBuild
198 '';
199
200 installPhase = ''
201 runHook preInstall
202 make -C builddir install LOCALSTATEDIR="$out/var/lib"
203 runHook postInstall
204 '';
205
206 postFixup = ''
207 substituteInPlace "$out/bin/run-singularity" \
208 --replace "/usr/bin/env ${projectName}" "$out/bin/${projectName}"
209 wrapProgram "$out/bin/${projectName}" \
210 --prefix PATH : "''${defaultPathInputs// /\/bin:}''${defaultPathInputs:+/bin:}"
211 # Make changes in the config file
212 ${lib.optionalString enableNvidiaContainerCli ''
213 substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \
214 --replace "use nvidia-container-cli = no" "use nvidia-container-cli = yes"
215 ''}
216 ${lib.optionalString (enableNvidiaContainerCli && projectName == "singularity") ''
217 substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \
218 --replace "# nvidia-container-cli path =" "nvidia-container-cli path = ${nvidia-docker}/bin/nvidia-container-cli"
219 ''}
220 ${lib.optionalString (removeCompat && (projectName != "singularity")) ''
221 unlink "$out/bin/singularity"
222 for file in "$out"/share/man/man?/singularity*.gz; do
223 if [[ -L "$file" ]]; then
224 unlink "$file"
225 fi
226 done
227 for file in "$out"/share/*-completion/completions/singularity; do
228 if [[ -e "$file" ]]
229 rm "$file"
230 done
231 ''}
232 ${lib.optionalString enableSuid (lib.warnIf (starterSuidPath == null) "${projectName}: Null starterSuidPath when enableSuid produces non-SUID-ed starter-suid and run-time permission denial." ''
233 chmod +x $out/libexec/${projectName}/bin/starter-suid
234 '')}
235 ${lib.optionalString (enableSuid && (starterSuidPath != null)) ''
236 mv "$out"/libexec/${projectName}/bin/starter-suid{,.orig}
237 ln -s ${lib.escapeShellArg starterSuidPath} "$out/libexec/${projectName}/bin/starter-suid"
238 ''}
239 '';
240
241 meta = with lib; {
242 description = "Application containers for linux" + extraDescription;
243 longDescription = ''
244 Singularity (the upstream) renamed themselves to Apptainer
245 to distinguish themselves from a fork made by Sylabs Inc.. See
246
247 https://sylabs.io/2021/05/singularity-community-edition
248 https://apptainer.org/news/community-announcement-20211130
249 '';
250 license = licenses.bsd3;
251 platforms = platforms.linux;
252 maintainers = with maintainers; [ jbedo ShamrockLee ];
253 mainProgram = projectName;
254 } // extraMeta;
255}).overrideAttrs (finalAttrs: prevAttrs: {
256 passthru = prevAttrs.passthru or { } // {
257 tests = {
258 image-hello-cowsay = singularity-tools.buildImage {
259 name = "hello-cowsay";
260 contents = [ hello cowsay ];
261 singularity = finalAttrs.finalPackage;
262 };
263 };
264 };
265})