From 409cbbe61a551410d109b739a5cb0959a2c8db16 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Wed, 24 Apr 2024 04:05:24 +0800 Subject: [PATCH 1/4] apptainer, singularity: prioritize original defaultPath Prefix the upstream-given defalutPath value over the one constructed by defaultPathInputs. Make SUID'ed binaries searchable out-of-the-box non-NixOS platforms. --- .../virtualization/singularity/generic.nix | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkgs/applications/virtualization/singularity/generic.nix b/pkgs/applications/virtualization/singularity/generic.nix index f27f58fda487..595730b1fe8a 100644 --- a/pkgs/applications/virtualization/singularity/generic.nix +++ b/pkgs/applications/virtualization/singularity/generic.nix @@ -196,8 +196,9 @@ in # causes redefinition of _FORTIFY_SOURCE hardeningDisable = [ "fortify3" ]; - # Packages to prefix to the Apptainer/Singularity container runtime default PATH - # Use overrideAttrs to override + # Packages to provide fallback bin paths + # to the Apptainer/Singularity container runtime default PATHs. + # Override with `.overrideAttrs`. defaultPathInputs = [ bash coreutils @@ -228,7 +229,7 @@ in lib.concatStringsSep " " [ "--replace-fail" (addShellDoubleQuotes (lib.escapeShellArg originalDefaultPath)) - (addShellDoubleQuotes ''$inputsDefaultPath''${inputsDefaultPath:+:}${lib.escapeShellArg originalDefaultPath}'') + (addShellDoubleQuotes ''${lib.escapeShellArg originalDefaultPath}''${inputsDefaultPath:+:}$inputsDefaultPath'') ] ) originalDefaultPaths } @@ -267,8 +268,10 @@ in postFixup = '' substituteInPlace "$out/bin/run-singularity" \ --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}" \ - --prefix PATH : "$inputsDefaultPath" + --suffix PATH : "$inputsDefaultPath" # Make changes in the config file ${lib.optionalString forceNvcCli '' substituteInPlace "$out/etc/${projectName}/${projectName}.conf" \ From f6d9b4b6fc7f376e5f5ecacace951f57c155045c Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Wed, 24 Apr 2024 03:55:30 +0800 Subject: [PATCH 2/4] apptainer, singularity: add argument systemBinPaths Use systemBinPaths as the new way to specify system bin paths, especifally for SUID'ed binaries. Deprecate arguments setuidmapPath and setgidmapPath in favour of systemBinPaths. Add NixOS configuration option programs.singularity.systemBinPath, with "/run/wrappers/bin" included by default. --- nixos/modules/programs/singularity.nix | 25 ++++++++++++--- .../virtualization/singularity/generic.nix | 31 ++++++++++++++----- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/nixos/modules/programs/singularity.nix b/nixos/modules/programs/singularity.nix index bc989ad2dbaf..d1115b361593 100644 --- a/nixos/modules/programs/singularity.nix +++ b/nixos/modules/programs/singularity.nix @@ -56,9 +56,12 @@ in enableFakeroot = lib.mkOption { type = lib.types.bool; default = true; - example = false; description = '' 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 { @@ -74,22 +77,34 @@ in 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 { programs.singularity.packageOverriden = ( cfg.package.override ( - lib.optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; } - // lib.optionalAttrs cfg.enableFakeroot { - newuidmapPath = "/run/wrappers/bin/newuidmap"; - newgidmapPath = "/run/wrappers/bin/newgidmap"; + { + systemBinPaths = cfg.systemBinPaths; } + // lib.optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; } // lib.optionalAttrs cfg.enableSuid { enableSuid = true; starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; } ) ); + programs.singularity.systemBinPaths = [ "/run/wrappers/bin" ]; environment.systemPackages = [ cfg.packageOverriden ]; security.wrappers."${cfg.packageOverriden.projectName}-suid" = lib.mkIf cfg.enableSuid { setuid = true; diff --git a/pkgs/applications/virtualization/singularity/generic.nix b/pkgs/applications/virtualization/singularity/generic.nix index 595730b1fe8a..684ca5937788 100644 --- a/pkgs/applications/virtualization/singularity/generic.nix +++ b/pkgs/applications/virtualization/singularity/generic.nix @@ -70,11 +70,19 @@ in # Whether to compile with SUID support enableSuid ? false, starterSuidPath ? null, - # newuidmapPath and newgidmapPath are to support --fakeroot - # where those SUID-ed executables are unavailable from the FHS system PATH. + # Extra system-wide /**/bin paths to prefix, + # 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 + # Deprecated in favour of systemBinPaths + # TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off newuidmapPath ? null, # Path to SUID-ed newgidmap executable + # Deprecated in favour of systemBinPaths + # TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off newgidmapPath ? null, # External LOCALSTATEDIR externalLocalStateDir ? null, @@ -99,18 +107,26 @@ in vendorHash ? _defaultGoVendorArgs.vendorHash, deleteVendor ? _defaultGoVendorArgs.deleteVendor, proxyVendor ? _defaultGoVendorArgs.proxyVendor, -}: +}@args: let + # Backward compatibility for privileged-un-utils. + # TODO(@ShamrockLee): Remove after Nixpkgs 24.05 branch-off. privileged-un-utils = if ((newuidmapPath == null) && (newgidmapPath == null)) then null else - (runCommandLocal "privileged-un-utils" { } '' + 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 = sep: f: attrs: @@ -207,7 +223,6 @@ in fuse2fs # Mount ext3 filesystems go mount # mount - privileged-un-utils squashfsTools # mksquashfs unsquashfs # Make / unpack squashfs image squashfuse # squashfuse_ll squashfuse # Mount (without unpacking) a squashfs image without privileges ] ++ lib.optional enableNvidiaContainerCli nvidia-docker; @@ -229,7 +244,7 @@ in lib.concatStringsSep " " [ "--replace-fail" (addShellDoubleQuotes (lib.escapeShellArg originalDefaultPath)) - (addShellDoubleQuotes ''${lib.escapeShellArg originalDefaultPath}''${inputsDefaultPath:+:}$inputsDefaultPath'') + (addShellDoubleQuotes ''$systemDefaultPath''${systemDefaultPath:+:}${lib.escapeShellArg originalDefaultPath}''${inputsDefaultPath:+:}$inputsDefaultPath'') ] ) originalDefaultPaths } @@ -271,6 +286,7 @@ in # Respect PATH from the environment/the user. # Fallback to bin paths provided by Nixpkgs packages. wrapProgram "$out/bin/${projectName}" \ + --suffix PATH : "$systemDefaultPath" \ --suffix PATH : "$inputsDefaultPath" # Make changes in the config file ${lib.optionalString forceNvcCli '' @@ -329,6 +345,7 @@ in }).overrideAttrs ( finalAttrs: prevAttrs: { + systemDefaultPath = lib.concatStringsSep ":" systemBinPaths; inputsDefaultPath = lib.makeBinPath finalAttrs.defaultPathInputs; passthru = prevAttrs.passthru or { } // { inherit sourceFilesWithDefaultPaths; From dbcf7cf697c601fc92da45453290b81587b87ef5 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Thu, 25 Apr 2024 15:35:32 +0800 Subject: [PATCH 3/4] apptainer, singularity: add release note entry about systemBinPaths Add a Nixpkgs 24.05 release note entry explaining the introduction of `systemBinPaths` argument, the prioritization of the original (FHS) `defaultPath` values, and the deprecation of arguments `newuidmapPath`, `newgidmapPath` and NixOS configuration option `programs.singularity.enableFakeroot`. --- nixos/doc/manual/release-notes/rl-2405.section.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 2729ded6090a..729257e51675 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -223,6 +223,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. +- `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 ```nix From c3026ac986b6b21409a0240dcad4a411dad0d419 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Thu, 25 Apr 2024 15:06:46 +0800 Subject: [PATCH 4/4] apptainer, singularity: warn abuot argument deprecation Warn when arguments newuidmapPath and newgidmapPath is used. --- .../virtualization/singularity/generic.nix | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkgs/applications/virtualization/singularity/generic.nix b/pkgs/applications/virtualization/singularity/generic.nix index 684ca5937788..1cac1d4f16c6 100644 --- a/pkgs/applications/virtualization/singularity/generic.nix +++ b/pkgs/applications/virtualization/singularity/generic.nix @@ -116,11 +116,15 @@ let if ((newuidmapPath == null) && (newgidmapPath == null)) then null else - runCommandLocal "privileged-un-utils" { } '' - mkdir -p "$out/bin" - ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap" - ln -s ${lib.escapeShellArg newgidmapPath} "$out/bin/newgidmap" - ''; + lib.warn + "${pname}: arguments newuidmapPath and newgidmapPath is deprecated in favour of systemBinPaths." + ( + 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.