Merge pull request #306730 from ShamrockLee/apptainer-default-path

apptainer, singularity: precede system-level bin paths in `defaultPath` and fix `singularity` image running
This commit is contained in:
Someone 2024-07-03 19:56:08 +00:00 committed by GitHub
commit 7cdac9fd12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 18 deletions

View File

@ -225,6 +225,19 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
- `appimageTools.wrapAppImage` now creates the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds. - `appimageTools.wrapAppImage` now creates the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds.
- `apptainer` and `singularity` now prioritize system-wide `PATH` over those constructed from dependent packages when searching for third-party utilities. The `PATH` to search for third-party utilities, known as `defaultPath` inside Apptainer/Singularity source code, is now constructed from the following sources, ordered by their precedence:
- `systemBinPaths`, a new argument introduced to specify system-wide `"/**/bin"` directories.
- The FHS `defaultPath` value set by Apptainer/Singularity developers, making Apptainer/Singularity work out of the box in FHS systems.
- `defaultPathInputs`, a list of packages to form the fall-back `PATH`.
This change is required to enable Sylabs SingularityCE (`singularity`) to run images, as it requires a `fusermount3` commant with the SUID bit set.
`newuidmapPath` and `newgidmapPath` arguments are deprecated in favour of `systemBinPaths`. Their support will be removed in future releases.
`programs.singularity.systemBinPaths` option is introduced to specify the `systemBinPaths` argument of the overridden package. It includes `"/run/wrappers/bin"` even if specified empty.
`programs.singularity.enableFakeroot` option is deprecated and has no effect. `--fakeroot` support is now always enabled as long as `programs.singularity.systemBinPaths` is not forcefully overridden.
- `azure-cli` now has extension support. For example, to install the `aks-preview` extension, use - `azure-cli` now has extension support. For example, to install the `aks-preview` extension, use
```nix ```nix

View File

@ -56,9 +56,12 @@ in
enableFakeroot = lib.mkOption { enableFakeroot = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
example = false;
description = '' description = ''
Whether to enable the `--fakeroot` support of Singularity/Apptainer. Whether to enable the `--fakeroot` support of Singularity/Apptainer.
This option is deprecated and has no effect.
`--fakeroot` support is enabled automatically,
as `systemBinPaths = [ "/run/wrappers/bin" ]` is always specified.
''; '';
}; };
enableSuid = lib.mkOption { enableSuid = lib.mkOption {
@ -74,22 +77,34 @@ in
Whether to enable the SUID support of Singularity/Apptainer. Whether to enable the SUID support of Singularity/Apptainer.
''; '';
}; };
systemBinPaths = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [ ];
description = ''
(Extra) system-wide /**/bin paths
for Apptainer/Singularity to find command-line utilities in.
`"/run/wrappers/bin"` is included by default to make
utilities with SUID bit set available to Apptainer/Singularity.
Use `lib.mkForce` to shadow the default values.
'';
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.singularity.packageOverriden = ( programs.singularity.packageOverriden = (
cfg.package.override ( cfg.package.override (
lib.optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; } {
// lib.optionalAttrs cfg.enableFakeroot { systemBinPaths = cfg.systemBinPaths;
newuidmapPath = "/run/wrappers/bin/newuidmap";
newgidmapPath = "/run/wrappers/bin/newgidmap";
} }
// lib.optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; }
// lib.optionalAttrs cfg.enableSuid { // lib.optionalAttrs cfg.enableSuid {
enableSuid = true; enableSuid = true;
starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid";
} }
) )
); );
programs.singularity.systemBinPaths = [ "/run/wrappers/bin" ];
environment.systemPackages = [ cfg.packageOverriden ]; environment.systemPackages = [ cfg.packageOverriden ];
security.wrappers."${cfg.packageOverriden.projectName}-suid" = lib.mkIf cfg.enableSuid { security.wrappers."${cfg.packageOverriden.projectName}-suid" = lib.mkIf cfg.enableSuid {
setuid = true; setuid = true;

View File

@ -70,11 +70,19 @@ in
# Whether to compile with SUID support # Whether to compile with SUID support
enableSuid ? false, enableSuid ? false,
starterSuidPath ? null, starterSuidPath ? null,
# newuidmapPath and newgidmapPath are to support --fakeroot # Extra system-wide /**/bin paths to prefix,
# where those SUID-ed executables are unavailable from the FHS system PATH. # useful to specify directories containing binaries with SUID bit set.
# The paths take higher precedence over the FHS system PATH specified
# inside the upstream source code.
# Include "/run/wrappers/bin" by default for the convenience of NixOS users.
systemBinPaths ? [ "/run/wrappers/bin" ],
# Path to SUID-ed newuidmap executable # Path to SUID-ed newuidmap executable
# Deprecated in favour of systemBinPaths
# TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off
newuidmapPath ? null, newuidmapPath ? null,
# Path to SUID-ed newgidmap executable # Path to SUID-ed newgidmap executable
# Deprecated in favour of systemBinPaths
# TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off
newgidmapPath ? null, newgidmapPath ? null,
# External LOCALSTATEDIR # External LOCALSTATEDIR
externalLocalStateDir ? null, externalLocalStateDir ? null,
@ -99,18 +107,30 @@ in
vendorHash ? _defaultGoVendorArgs.vendorHash, vendorHash ? _defaultGoVendorArgs.vendorHash,
deleteVendor ? _defaultGoVendorArgs.deleteVendor, deleteVendor ? _defaultGoVendorArgs.deleteVendor,
proxyVendor ? _defaultGoVendorArgs.proxyVendor, proxyVendor ? _defaultGoVendorArgs.proxyVendor,
}: }@args:
let let
# Backward compatibility for privileged-un-utils.
# TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off.
privileged-un-utils = privileged-un-utils =
if ((newuidmapPath == null) && (newgidmapPath == null)) then if ((newuidmapPath == null) && (newgidmapPath == null)) then
null null
else else
(runCommandLocal "privileged-un-utils" { } '' lib.warn
mkdir -p "$out/bin" "${pname}: arguments newuidmapPath and newgidmapPath is deprecated in favour of systemBinPaths."
ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap" (
ln -s ${lib.escapeShellArg newgidmapPath} "$out/bin/newgidmap" runCommandLocal "privileged-un-utils" { } ''
''); mkdir -p "$out/bin"
ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap"
ln -s ${lib.escapeShellArg newgidmapPath} "$out/bin/newgidmap"
''
);
# Backward compatibility for privileged-un-utils.
# TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off.
systemBinPaths =
lib.optional (privileged-un-utils != null) (lib.makeBinPath [ privileged-un-utils ])
++ args.systemBinPaths or [ "/run/wrappers/bin" ];
concatMapStringAttrsSep = concatMapStringAttrsSep =
sep: f: attrs: sep: f: attrs:
@ -196,8 +216,9 @@ in
# causes redefinition of _FORTIFY_SOURCE # causes redefinition of _FORTIFY_SOURCE
hardeningDisable = [ "fortify3" ]; hardeningDisable = [ "fortify3" ];
# Packages to prefix to the Apptainer/Singularity container runtime default PATH # Packages to provide fallback bin paths
# Use overrideAttrs to override # to the Apptainer/Singularity container runtime default PATHs.
# Override with `<pkg>.overrideAttrs`.
defaultPathInputs = [ defaultPathInputs = [
bash bash
coreutils coreutils
@ -206,7 +227,6 @@ in
fuse2fs # Mount ext3 filesystems fuse2fs # Mount ext3 filesystems
go go
mount # mount mount # mount
privileged-un-utils
squashfsTools # mksquashfs unsquashfs # Make / unpack squashfs image squashfsTools # mksquashfs unsquashfs # Make / unpack squashfs image
squashfuse # squashfuse_ll squashfuse # Mount (without unpacking) a squashfs image without privileges squashfuse # squashfuse_ll squashfuse # Mount (without unpacking) a squashfs image without privileges
] ++ lib.optional enableNvidiaContainerCli nvidia-docker; ] ++ lib.optional enableNvidiaContainerCli nvidia-docker;
@ -228,7 +248,7 @@ in
lib.concatStringsSep " " [ lib.concatStringsSep " " [
"--replace-fail" "--replace-fail"
(addShellDoubleQuotes (lib.escapeShellArg originalDefaultPath)) (addShellDoubleQuotes (lib.escapeShellArg originalDefaultPath))
(addShellDoubleQuotes ''$inputsDefaultPath''${inputsDefaultPath:+:}${lib.escapeShellArg originalDefaultPath}'') (addShellDoubleQuotes ''$systemDefaultPath''${systemDefaultPath:+:}${lib.escapeShellArg originalDefaultPath}''${inputsDefaultPath:+:}$inputsDefaultPath'')
] ]
) originalDefaultPaths ) originalDefaultPaths
} }
@ -267,8 +287,11 @@ in
postFixup = '' postFixup = ''
substituteInPlace "$out/bin/run-singularity" \ substituteInPlace "$out/bin/run-singularity" \
--replace "/usr/bin/env ${projectName}" "$out/bin/${projectName}" --replace "/usr/bin/env ${projectName}" "$out/bin/${projectName}"
# Respect PATH from the environment/the user.
# Fallback to bin paths provided by Nixpkgs packages.
wrapProgram "$out/bin/${projectName}" \ wrapProgram "$out/bin/${projectName}" \
--prefix PATH : "$inputsDefaultPath" --suffix PATH : "$systemDefaultPath" \
--suffix PATH : "$inputsDefaultPath"
# Make changes in the config file # Make changes in the config file
${lib.optionalString forceNvcCli '' ${lib.optionalString forceNvcCli ''
substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \ substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \
@ -326,6 +349,7 @@ in
}).overrideAttrs }).overrideAttrs
( (
finalAttrs: prevAttrs: { finalAttrs: prevAttrs: {
systemDefaultPath = lib.concatStringsSep ":" systemBinPaths;
inputsDefaultPath = lib.makeBinPath finalAttrs.defaultPathInputs; inputsDefaultPath = lib.makeBinPath finalAttrs.defaultPathInputs;
passthru = prevAttrs.passthru or { } // { passthru = prevAttrs.passthru or { } // {
inherit sourceFilesWithDefaultPaths; inherit sourceFilesWithDefaultPaths;