Merge pull request #306656 from ShamrockLee/apptainer-format

apptainer, singularity: format Nix expression according to Nix RFC 166
This commit is contained in:
Someone 2024-04-25 19:45:51 +00:00 committed by GitHub
commit 5e05a5e3c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 264 additions and 226 deletions

View File

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }: {
config,
pkgs,
lib,
...
}:
with lib; with lib;
let let
@ -12,9 +17,7 @@ in
Whether to install Singularity/Apptainer with system-level overriding such as SUID support. Whether to install Singularity/Apptainer with system-level overriding such as SUID support.
''; '';
}; };
package = mkPackageOption pkgs "singularity" { package = mkPackageOption pkgs "singularity" { example = "apptainer"; };
example = "apptainer";
};
packageOverriden = mkOption { packageOverriden = mkOption {
type = types.nullOr types.package; type = types.nullOr types.package;
default = null; default = null;
@ -75,17 +78,19 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.singularity.packageOverriden = (cfg.package.override ( programs.singularity.packageOverriden = (
optionalAttrs cfg.enableExternalLocalStateDir { cfg.package.override (
externalLocalStateDir = "/var/lib"; optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; }
} // optionalAttrs cfg.enableFakeroot { // optionalAttrs cfg.enableFakeroot {
newuidmapPath = "/run/wrappers/bin/newuidmap"; newuidmapPath = "/run/wrappers/bin/newuidmap";
newgidmapPath = "/run/wrappers/bin/newgidmap"; newgidmapPath = "/run/wrappers/bin/newgidmap";
} // optionalAttrs cfg.enableSuid { }
enableSuid = true; // optionalAttrs cfg.enableSuid {
starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; enableSuid = true;
} starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid";
)); }
)
);
environment.systemPackages = [ cfg.packageOverriden ]; environment.systemPackages = [ cfg.packageOverriden ];
security.wrappers."${cfg.packageOverriden.projectName}-suid" = mkIf cfg.enableSuid { security.wrappers."${cfg.packageOverriden.projectName}-suid" = mkIf cfg.enableSuid {
setuid = true; setuid = true;
@ -97,5 +102,4 @@ in
"d /var/lib/${cfg.packageOverriden.projectName}/mnt/session 0770 root root -" "d /var/lib/${cfg.packageOverriden.projectName}/mnt/session 0770 root root -"
]; ];
}; };
} }

View File

@ -1,107 +1,111 @@
# Configurations that should only be overrided by # Configurations that should only be overrided by
# overrideAttrs # overrideAttrs
{ pname {
, version pname,
, src version,
, projectName # "apptainer" or "singularity" src,
, vendorHash ? null projectName, # "apptainer" or "singularity"
, deleteVendor ? false vendorHash ? null,
, proxyVendor ? false deleteVendor ? false,
, extraConfigureFlags ? [ ] proxyVendor ? false,
, extraDescription ? "" extraConfigureFlags ? [ ],
, extraMeta ? { } extraDescription ? "",
extraMeta ? { },
}: }:
let let
# Workaround for vendor-related attributes not overridable (#86349) # Workaround for vendor-related attributes not overridable (#86349)
# should be removed when the issue is resolved # should be removed when the issue is resolved
_defaultGoVendorArgs = { _defaultGoVendorArgs = {
inherit inherit vendorHash deleteVendor proxyVendor;
vendorHash
deleteVendor
proxyVendor
;
}; };
in in
{ lib {
, buildGoModule lib,
, runCommandLocal buildGoModule,
runCommandLocal,
substituteAll,
# Native build inputs # Native build inputs
, addDriverRunpath addDriverRunpath,
, makeWrapper makeWrapper,
, pkg-config pkg-config,
, util-linux util-linux,
, which which,
# Build inputs # Build inputs
, bash bash,
, callPackage callPackage,
, conmon conmon,
, coreutils coreutils,
, cryptsetup cryptsetup,
, e2fsprogs e2fsprogs,
, fakeroot fakeroot,
, fuse2fs ? e2fsprogs.fuse2fs fuse2fs ? e2fsprogs.fuse2fs,
, go go,
, gpgme gpgme,
, libseccomp libseccomp,
, libuuid libuuid,
# This is for nvidia-container-cli # This is for nvidia-container-cli
, nvidia-docker nvidia-docker,
, openssl openssl,
, squashfsTools squashfsTools,
, squashfuse squashfuse,
# Test dependencies # Test dependencies
, singularity-tools singularity-tools,
, cowsay cowsay,
, hello hello,
# Overridable configurations # Overridable configurations
, enableNvidiaContainerCli ? true enableNvidiaContainerCli ? true,
# --nvccli currently requires extra privileges: # --nvccli currently requires extra privileges:
# https://github.com/apptainer/apptainer/issues/1893#issuecomment-1881240800 # https://github.com/apptainer/apptainer/issues/1893#issuecomment-1881240800
, forceNvcCli ? false forceNvcCli ? false,
# Compile with seccomp support # Compile with seccomp support
# SingularityCE 3.10.0 and above requires explicit --without-seccomp when libseccomp is not available. # SingularityCE 3.10.0 and above requires explicit --without-seccomp when libseccomp is not available.
, enableSeccomp ? true enableSeccomp ? true,
# Whether the configure script treat SUID support as default # Whether the configure script treat SUID support as default
# When equal to enableSuid, it supress the --with-suid / --without-suid build flag # When equal to enableSuid, it supress the --with-suid / --without-suid build flag
# It can be set to `null` to always pass either --with-suid or --without-suided # It can be set to `null` to always pass either --with-suid or --without-suided
# Type: null or boolean # Type: null or boolean
, defaultToSuid ? true defaultToSuid ? true,
# Whether to compile with SUID support # Whether to compile with SUID support
, enableSuid ? false enableSuid ? false,
, starterSuidPath ? null starterSuidPath ? null,
, substituteAll
# newuidmapPath and newgidmapPath are to support --fakeroot # newuidmapPath and newgidmapPath are to support --fakeroot
# where those SUID-ed executables are unavailable from the FHS system PATH. # where those SUID-ed executables are unavailable from the FHS system PATH.
# Path to SUID-ed newuidmap executable # Path to SUID-ed newuidmap executable
, newuidmapPath ? null newuidmapPath ? null,
# Path to SUID-ed newgidmap executable # Path to SUID-ed newgidmap executable
, newgidmapPath ? null newgidmapPath ? null,
# External LOCALSTATEDIR # External LOCALSTATEDIR
, externalLocalStateDir ? null externalLocalStateDir ? null,
# Remove the symlinks to `singularity*` when projectName != "singularity" # Remove the symlinks to `singularity*` when projectName != "singularity"
, removeCompat ? false removeCompat ? false,
# Workaround #86349 # Workaround #86349
# should be removed when the issue is resolved # should be removed when the issue is resolved
, vendorHash ? _defaultGoVendorArgs.vendorHash vendorHash ? _defaultGoVendorArgs.vendorHash,
, deleteVendor ? _defaultGoVendorArgs.deleteVendor deleteVendor ? _defaultGoVendorArgs.deleteVendor,
, proxyVendor ? _defaultGoVendorArgs.proxyVendor proxyVendor ? _defaultGoVendorArgs.proxyVendor,
}: }:
let let
defaultPathOriginal = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"; defaultPathOriginal = "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin";
privileged-un-utils = if ((newuidmapPath == null) && (newgidmapPath == null)) then null else privileged-un-utils =
(runCommandLocal "privileged-un-utils" { } '' if ((newuidmapPath == null) && (newgidmapPath == null)) then
mkdir -p "$out/bin" null
ln -s ${lib.escapeShellArg newuidmapPath} "$out/bin/newuidmap" else
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"
'');
in in
(buildGoModule { (buildGoModule {
inherit pname version src; inherit pname version src;
patches = lib.optionals (projectName == "apptainer") [ patches = lib.optionals (projectName == "apptainer") [
(substituteAll { src = ./apptainer/0001-ldCache-patch-for-driverLink.patch; inherit (addDriverRunpath) driverLink; }) (substituteAll {
src = ./apptainer/0001-ldCache-patch-for-driverLink.patch;
inherit (addDriverRunpath) driverLink;
})
]; ];
# Override vendorHash with the output got from # Override vendorHash with the output got from
@ -138,29 +142,36 @@ in
# apptainer/apptainer: https://github.com/apptainer/apptainer/blob/main/dist/debian/control # apptainer/apptainer: https://github.com/apptainer/apptainer/blob/main/dist/debian/control
# sylabs/singularity: https://github.com/sylabs/singularity/blob/main/debian/control # sylabs/singularity: https://github.com/sylabs/singularity/blob/main/debian/control
buildInputs = [ buildInputs =
bash # To patch /bin/sh shebangs. [
conmon bash # To patch /bin/sh shebangs.
cryptsetup conmon
gpgme cryptsetup
libuuid gpgme
openssl libuuid
squashfsTools # Required at build time by SingularityCE openssl
] squashfsTools # Required at build time by SingularityCE
++ lib.optional enableNvidiaContainerCli nvidia-docker ]
++ lib.optional enableSeccomp libseccomp # Optional dependencies.
; # Formatting: Optional dependencies are likely to increase.
# Don't squash them into the same line.
++ lib.optional enableNvidiaContainerCli nvidia-docker
++ lib.optional enableSeccomp libseccomp;
configureScript = "./mconfig"; configureScript = "./mconfig";
configureFlags = [ configureFlags =
"--localstatedir=${if externalLocalStateDir != null then externalLocalStateDir else "${placeholder "out"}/var/lib"}" [
"--runstatedir=/var/run" "--localstatedir=${
] if externalLocalStateDir != null then externalLocalStateDir else "${placeholder "out"}/var/lib"
++ lib.optional (!enableSeccomp) "--without-seccomp" }"
++ lib.optional (enableSuid != defaultToSuid) (if enableSuid then "--with-suid" else "--without-suid") "--runstatedir=/var/run"
++ extraConfigureFlags ]
; ++ lib.optional (!enableSeccomp) "--without-seccomp"
++ lib.optional (enableSuid != defaultToSuid) (
if enableSuid then "--with-suid" else "--without-suid"
)
++ extraConfigureFlags;
# causes redefinition of _FORTIFY_SOURCE # causes redefinition of _FORTIFY_SOURCE
hardeningDisable = [ "fortify3" ]; hardeningDisable = [ "fortify3" ];
@ -177,9 +188,7 @@ in
privileged-un-utils 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
;
postPatch = '' postPatch = ''
if [[ ! -e .git || ! -e VERSION ]]; then if [[ ! -e .git || ! -e VERSION ]]; then
@ -249,70 +258,86 @@ in
rm "$file" rm "$file"
done done
''} ''}
${lib.optionalString enableSuid (lib.warnIf (starterSuidPath == null) "${projectName}: Null starterSuidPath when enableSuid produces non-SUID-ed starter-suid and run-time permission denial." '' ${lib.optionalString enableSuid (
chmod +x $out/libexec/${projectName}/bin/starter-suid lib.warnIf (starterSuidPath == null)
'')} "${projectName}: Null starterSuidPath when enableSuid produces non-SUID-ed starter-suid and run-time permission denial."
''
chmod +x $out/libexec/${projectName}/bin/starter-suid
''
)}
${lib.optionalString (enableSuid && (starterSuidPath != null)) '' ${lib.optionalString (enableSuid && (starterSuidPath != null)) ''
mv "$out"/libexec/${projectName}/bin/starter-suid{,.orig} mv "$out"/libexec/${projectName}/bin/starter-suid{,.orig}
ln -s ${lib.escapeShellArg starterSuidPath} "$out/libexec/${projectName}/bin/starter-suid" ln -s ${lib.escapeShellArg starterSuidPath} "$out/libexec/${projectName}/bin/starter-suid"
''} ''}
''; '';
meta = with lib; { meta =
description = "Application containers for linux" + extraDescription; with lib;
longDescription = '' {
Singularity (the upstream) renamed themselves to Apptainer description = "Application containers for linux" + extraDescription;
to distinguish themselves from a fork made by Sylabs Inc.. See longDescription = ''
Singularity (the upstream) renamed themselves to Apptainer
to distinguish themselves from a fork made by Sylabs Inc.. See
https://sylabs.io/2021/05/singularity-community-edition https://sylabs.io/2021/05/singularity-community-edition
https://apptainer.org/news/community-announcement-20211130 https://apptainer.org/news/community-announcement-20211130
''; '';
license = licenses.bsd3; license = licenses.bsd3;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = with maintainers; [ jbedo ShamrockLee ]; maintainers = with maintainers; [
mainProgram = projectName; jbedo
} // extraMeta; ShamrockLee
}).overrideAttrs (finalAttrs: prevAttrs: { ];
passthru = prevAttrs.passthru or { } // { mainProgram = projectName;
tests = { }
image-hello-cowsay = singularity-tools.buildImage { // extraMeta;
name = "hello-cowsay"; }).overrideAttrs
contents = [ hello cowsay ]; (
singularity = finalAttrs.finalPackage; finalAttrs: prevAttrs: {
}; passthru = prevAttrs.passthru or { } // {
}; tests = {
gpuChecks = lib.optionalAttrs (projectName == "apptainer") { image-hello-cowsay = singularity-tools.buildImage {
# Should be in tests, but Ofborg would skip image-hello-cowsay because name = "hello-cowsay";
# saxpy is unfree. contents = [
image-saxpy = callPackage hello
({ singularity-tools, cudaPackages }: cowsay
singularity-tools.buildImage { ];
name = "saxpy";
contents = [ cudaPackages.saxpy ];
memSize = 2048;
diskSize = 2048;
singularity = finalAttrs.finalPackage; singularity = finalAttrs.finalPackage;
}) };
{ }; };
saxpy = gpuChecks = lib.optionalAttrs (projectName == "apptainer") {
callPackage # Should be in tests, but Ofborg would skip image-hello-cowsay because
({ runCommand, writeShellScriptBin }: # saxpy is unfree.
image-saxpy = callPackage (
{ singularity-tools, cudaPackages }:
singularity-tools.buildImage {
name = "saxpy";
contents = [ cudaPackages.saxpy ];
memSize = 2048;
diskSize = 2048;
singularity = finalAttrs.finalPackage;
}
) { };
saxpy = callPackage (
{ runCommand, writeShellScriptBin }:
let let
unwrapped = writeShellScriptBin "apptainer-cuda-saxpy" unwrapped = writeShellScriptBin "apptainer-cuda-saxpy" ''
'' ${lib.getExe finalAttrs.finalPackage} exec --nv $@ ${finalAttrs.passthru.gpuChecks.image-saxpy} saxpy
${lib.getExe finalAttrs.finalPackage} exec --nv $@ ${finalAttrs.passthru.gpuChecks.image-saxpy} saxpy '';
'';
in in
runCommand "run-apptainer-cuda-saxpy" runCommand "run-apptainer-cuda-saxpy"
{ {
requiredSystemFeatures = [ "cuda" ]; requiredSystemFeatures = [ "cuda" ];
nativeBuildInputs = [ unwrapped ]; nativeBuildInputs = [ unwrapped ];
passthru = { inherit unwrapped; }; passthru = {
inherit unwrapped;
};
} }
'' ''
apptainer-cuda-saxpy apptainer-cuda-saxpy
'') ''
{ }; ) { };
}; };
}; };
}) }
)

View File

@ -1,89 +1,98 @@
{ callPackage {
, fetchFromGitHub callPackage,
, nixos fetchFromGitHub,
, conmon nixos,
conmon,
}: }:
let let
apptainer = callPackage apptainer =
(import ./generic.nix rec { callPackage
pname = "apptainer"; (import ./generic.nix rec {
version = "1.3.1"; pname = "apptainer";
projectName = "apptainer"; version = "1.3.1";
projectName = "apptainer";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "apptainer"; owner = "apptainer";
repo = "apptainer"; repo = "apptainer";
rev = "refs/tags/v${version}"; rev = "refs/tags/v${version}";
hash = "sha256-XhJecINx8jC6pRzIoM4nC6Aunj40xL8EmYIA4UizfAY="; hash = "sha256-XhJecINx8jC6pRzIoM4nC6Aunj40xL8EmYIA4UizfAY=";
};
# Update by running
# nix-prefetch -E "{ sha256 }: ((import ./. { }).apptainer.override { vendorHash = sha256; }).goModules"
# at the root directory of the Nixpkgs repository
vendorHash = "sha256-MXW1U13uDRAx4tqZvqsuJvoD22nEL2gcxiGaa/6zwU0=";
extraDescription = " (previously known as Singularity)";
extraMeta.homepage = "https://apptainer.org";
})
{
# Apptainer doesn't depend on conmon
conmon = null;
# Apptainer builders require explicit --with-suid / --without-suid flag
# when building on a system with disabled unprivileged namespace.
# See https://github.com/NixOS/nixpkgs/pull/215690#issuecomment-1426954601
defaultToSuid = null;
}; };
# Update by running singularity =
# nix-prefetch -E "{ sha256 }: ((import ./. { }).apptainer.override { vendorHash = sha256; }).goModules" callPackage
# at the root directory of the Nixpkgs repository (import ./generic.nix rec {
vendorHash = "sha256-MXW1U13uDRAx4tqZvqsuJvoD22nEL2gcxiGaa/6zwU0="; pname = "singularity-ce";
version = "4.1.2";
projectName = "singularity";
extraDescription = " (previously known as Singularity)"; src = fetchFromGitHub {
extraMeta.homepage = "https://apptainer.org"; owner = "sylabs";
}) repo = "singularity";
{ rev = "refs/tags/v${version}";
# Apptainer doesn't depend on conmon hash = "sha256-/KTDdkCMkZ5hO+VYHzw9vB8FDWxg7PS1yb2waRJQngY=";
conmon = null; };
# Apptainer builders require explicit --with-suid / --without-suid flag # Update by running
# when building on a system with disabled unprivileged namespace. # nix-prefetch -E "{ sha256 }: ((import ./. { }).singularity.override { vendorHash = sha256; }).goModules"
# See https://github.com/NixOS/nixpkgs/pull/215690#issuecomment-1426954601 # at the root directory of the Nixpkgs repository
defaultToSuid = null; vendorHash = "sha256-4Nxj2PzZmFdvouWKyXLFDk8iuRhFuvyPW/+VRTw75Zw=";
};
singularity = callPackage # Do not build conmon and squashfuse from the Git submodule sources,
(import ./generic.nix rec { # Use Nixpkgs provided version
pname = "singularity-ce"; extraConfigureFlags = [
version = "4.1.2"; "--without-conmon"
projectName = "singularity"; "--without-squashfuse"
];
src = fetchFromGitHub { extraDescription = " (Sylabs Inc's fork of Singularity, a.k.a. SingularityCE)";
owner = "sylabs"; extraMeta.homepage = "https://sylabs.io/";
repo = "singularity"; })
rev = "refs/tags/v${version}"; {
hash = "sha256-/KTDdkCMkZ5hO+VYHzw9vB8FDWxg7PS1yb2waRJQngY="; # Sylabs SingularityCE builders defaults to set the SUID flag
# on UNIX-like platforms,
# and only have --without-suid but not --with-suid.
defaultToSuid = true;
}; };
# Update by running genOverridenNixos =
# nix-prefetch -E "{ sha256 }: ((import ./. { }).singularity.override { vendorHash = sha256; }).goModules" package: packageName:
# at the root directory of the Nixpkgs repository (nixos {
vendorHash = "sha256-4Nxj2PzZmFdvouWKyXLFDk8iuRhFuvyPW/+VRTw75Zw="; programs.singularity = {
enable = true;
inherit package;
};
}).config.programs.singularity.packageOverriden.overrideAttrs
(oldAttrs: {
meta = oldAttrs.meta // {
description = "";
longDescription = ''
This package produces identical store derivations to `pkgs.${packageName}`
overriden and installed by the NixOS module `programs.singularity`
with default configuration.
# Do not build conmon and squashfuse from the Git submodule sources, This is for binary substitutes only. Use pkgs.${packageName} instead.
# Use Nixpkgs provided version '';
extraConfigureFlags = [ };
"--without-conmon" });
"--without-squashfuse"
];
extraDescription = " (Sylabs Inc's fork of Singularity, a.k.a. SingularityCE)";
extraMeta.homepage = "https://sylabs.io/";
})
{
defaultToSuid = true;
};
genOverridenNixos = package: packageName: (nixos {
programs.singularity = {
enable = true;
inherit package;
};
}).config.programs.singularity.packageOverriden.overrideAttrs (oldAttrs: {
meta = oldAttrs.meta // {
description = "";
longDescription = ''
This package produces identical store derivations to `pkgs.${packageName}`
overriden and installed by the NixOS module `programs.singularity`
with default configuration.
This is for binary substitutes only. Use pkgs.${packageName} instead.
'';
};
});
in in
{ {
inherit apptainer singularity; inherit apptainer singularity;