diff options
author | Alyssa Ross <hi@alyssa.is> | 2019-06-12 09:59:45 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2019-06-18 18:14:17 +0000 |
commit | c5571a126859eb658ffd7340cb580f7d91f12bb6 (patch) | |
tree | 577573c3bf14d9849246d52daece719a10eaf138 /nixpkgs/pkgs/build-support | |
parent | 828bd4e8ddcbcd354ddfd99f55af69ee8ff5d9e7 (diff) | |
parent | 98e3b90b6c8f400ae5438ef868eb992a64b75ce5 (diff) | |
download | nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar.gz nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar.bz2 nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar.lz nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar.xz nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.tar.zst nixlib-c5571a126859eb658ffd7340cb580f7d91f12bb6.zip |
Merge commit '98e3b90b6c8f400ae5438ef868eb992a64b75ce5'
Diffstat (limited to 'nixpkgs/pkgs/build-support')
10 files changed, 129 insertions, 41 deletions
diff --git a/nixpkgs/pkgs/build-support/add-opengl-runpath/default.nix b/nixpkgs/pkgs/build-support/add-opengl-runpath/default.nix new file mode 100644 index 000000000000..5cab0937e074 --- /dev/null +++ b/nixpkgs/pkgs/build-support/add-opengl-runpath/default.nix @@ -0,0 +1,12 @@ +{ lib, stdenv }: + +stdenv.mkDerivation { + name = "add-opengl-runpath"; + + driverLink = "/run/opengl-driver" + lib.optionalString stdenv.isi686 "-32"; + + buildCommand = '' + mkdir -p $out/nix-support + substituteAll ${./setup-hook.sh} $out/nix-support/setup-hook + ''; +} diff --git a/nixpkgs/pkgs/build-support/add-opengl-runpath/setup-hook.sh b/nixpkgs/pkgs/build-support/add-opengl-runpath/setup-hook.sh new file mode 100644 index 000000000000..e556e7ead2a7 --- /dev/null +++ b/nixpkgs/pkgs/build-support/add-opengl-runpath/setup-hook.sh @@ -0,0 +1,29 @@ +# Set RUNPATH so that driver libraries in /run/opengl-driver(-32)/lib can be found. +# This is needed to not rely on LD_LIBRARY_PATH which does not work with setuid +# executables. Fixes https://github.com/NixOS/nixpkgs/issues/22760. It must be run +# in postFixup because RUNPATH stripping in fixup would undo it. Note that patchelf +# actually sets RUNPATH not RPATH, which applies only to dependencies of the binary +# it set on (including for dlopen), so the RUNPATH must indeed be set on these +# libraries and would not work if set only on executables. +addOpenGLRunpath() { + local forceRpath= + + while [ $# -gt 0 ]; do + case "$1" in + --) shift; break;; + --force-rpath) shift; forceRpath=1;; + --*) + echo "addOpenGLRunpath: ERROR: Invalid command line" \ + "argument: $1" >&2 + return 1;; + *) break;; + esac + done + + for file in "$@"; do + if ! isELF "$file"; then continue; fi + local origRpath="$(patchelf --print-rpath "$file")" + patchelf --set-rpath "@driverLink@/lib:$origRpath" ${forceRpath:+--force-rpath} "$file" + done +} + diff --git a/nixpkgs/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c b/nixpkgs/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c index 0e9e36bc3014..dcb2e97aa932 100644 --- a/nixpkgs/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c +++ b/nixpkgs/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c @@ -7,28 +7,43 @@ #include <sched.h> #include <unistd.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/syscall.h> + #define fail(s, err) g_error("%s: %s: %s", __func__, s, g_strerror(err)) #define fail_if(expr) \ if (expr) \ fail(#expr, errno); -#include <ftw.h> +const gchar *bind_blacklist[] = {"bin", "etc", "host", "real-host", "usr", "lib", "lib64", "lib32", "sbin", NULL}; -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> +int pivot_root(const char *new_root, const char *put_old) { + return syscall(SYS_pivot_root, new_root, put_old); +} -const gchar *bind_blacklist[] = {"bin", "etc", "host", "usr", "lib", "lib64", "lib32", "sbin", NULL}; +void mount_tmpfs(const gchar *target) { + fail_if(mount("none", target, "tmpfs", 0, NULL)); +} void bind_mount(const gchar *source, const gchar *target) { fail_if(g_mkdir(target, 0755)); - fail_if(mount(source, target, "bind", MS_BIND | MS_REC, NULL)); + fail_if(mount(source, target, NULL, MS_BIND | MS_REC, NULL)); } -void bind_mount_host(const gchar *host, const gchar *guest) { +const gchar *create_tmpdir() { + gchar *prefix = + g_build_filename(g_get_tmp_dir(), "chrootenvXXXXXX", NULL); + fail_if(!g_mkdtemp_full(prefix, 0755)); + return prefix; +} + +void pivot_host(const gchar *guest) { g_autofree gchar *point = g_build_filename(guest, "host", NULL); - bind_mount(host, point); + fail_if(g_mkdir(point, 0755)); + fail_if(pivot_root(guest, point)); } void bind_mount_item(const gchar *host, const gchar *guest, const gchar *name) { @@ -40,19 +55,22 @@ void bind_mount_item(const gchar *host, const gchar *guest, const gchar *name) { } void bind(const gchar *host, const gchar *guest) { + mount_tmpfs(guest); + pivot_host(guest); + + g_autofree gchar *host_dir = g_build_filename("/host", host, NULL); + g_autoptr(GError) err = NULL; - g_autoptr(GDir) dir = g_dir_open(host, 0, &err); + g_autoptr(GDir) dir = g_dir_open(host_dir, 0, &err); if (err != NULL) fail("g_dir_open", errno); const gchar *item; - while (item = g_dir_read_name(dir)) + while ((item = g_dir_read_name(dir))) if (!g_strv_contains(bind_blacklist, item)) - bind_mount_item(host, guest, item); - - bind_mount_host(host, guest); + bind_mount_item(host_dir, "/", item); } void spit(const char *path, char *fmt, ...) { @@ -68,11 +86,6 @@ void spit(const char *path, char *fmt, ...) { fclose(f); } -int nftw_remove(const char *path, const struct stat *sb, int type, - struct FTW *ftw) { - return remove(path); -} - int main(gint argc, gchar **argv) { const gchar *self = *argv++; @@ -81,15 +94,7 @@ int main(gint argc, gchar **argv) { return 1; } - if (g_getenv("NIX_CHROOTENV")) - g_warning("chrootenv doesn't stack!"); - else - g_setenv("NIX_CHROOTENV", "", TRUE); - - g_autofree gchar *prefix = - g_build_filename(g_get_tmp_dir(), "chrootenvXXXXXX", NULL); - - fail_if(!g_mkdtemp_full(prefix, 0755)); + g_autofree const gchar *prefix = create_tmpdir(); pid_t cpid = fork(); @@ -115,9 +120,24 @@ int main(gint argc, gchar **argv) { spit("/proc/self/uid_map", "%d %d 1", uid, uid); spit("/proc/self/gid_map", "%d %d 1", gid, gid); - bind("/", prefix); + // If there is a /host directory, assume this is nested chrootenv and use it as host instead. + gboolean nested_host = g_file_test("/host", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR); + g_autofree const gchar *host = nested_host ? "/host" : "/"; + + bind(host, prefix); + + // Replace /host by an actual (inner) /host. + if (nested_host) { + fail_if(g_mkdir("/real-host", 0755)); + fail_if(mount("/host/host", "/real-host", NULL, MS_BIND | MS_REC, NULL)); + // For some reason umount("/host") returns EBUSY even immediately after + // pivot_root. We detach it at least to keep `/proc/mounts` from blowing + // up in nested cases. + fail_if(umount2("/host", MNT_DETACH)); + fail_if(mount("/real-host", "/host", NULL, MS_MOVE, NULL)); + fail_if(rmdir("/real-host")); + } - fail_if(chroot(prefix)); fail_if(chdir("/")); fail_if(execvp(*argv, argv)); } @@ -126,8 +146,7 @@ int main(gint argc, gchar **argv) { int status; fail_if(waitpid(cpid, &status, 0) != cpid); - fail_if(nftw(prefix, nftw_remove, getdtablesize(), - FTW_DEPTH | FTW_MOUNT | FTW_PHYS)); + fail_if(rmdir(prefix)); if (WIFEXITED(status)) return WEXITSTATUS(status); diff --git a/nixpkgs/pkgs/build-support/build-fhs-userenv/env.nix b/nixpkgs/pkgs/build-support/build-fhs-userenv/env.nix index be83c9da2108..295b17eec67c 100644 --- a/nixpkgs/pkgs/build-support/build-fhs-userenv/env.nix +++ b/nixpkgs/pkgs/build-support/build-fhs-userenv/env.nix @@ -52,8 +52,8 @@ let etcProfile = writeText "profile" '' export PS1='${name}-chrootenv:\u@\h:\w\$ ' export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive' - export LD_LIBRARY_PATH='/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32' - export PATH='/run/wrappers/bin:/usr/bin:/usr/sbin' + export LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32:$LD_LIBRARY_PATH" + export PATH="/run/wrappers/bin:/usr/bin:/usr/sbin:$PATH" export TZDIR='/etc/zoneinfo' # Force compilers and other tools to look in default search paths diff --git a/nixpkgs/pkgs/build-support/docker/examples.nix b/nixpkgs/pkgs/build-support/docker/examples.nix index ac21be907b83..29eea33a7e18 100644 --- a/nixpkgs/pkgs/build-support/docker/examples.nix +++ b/nixpkgs/pkgs/build-support/docker/examples.nix @@ -226,4 +226,12 @@ rec { ''; }; + # 14. Create another layered image, for comparing layers with image 10. + another-layered-image = pkgs.dockerTools.buildLayeredImage { + name = "another-layered-image"; + tag = "latest"; + config.Cmd = [ "${pkgs.hello}/bin/hello" ]; + contents = [ pkgs.hello ]; + }; + } diff --git a/nixpkgs/pkgs/build-support/docker/store-path-to-layer.sh b/nixpkgs/pkgs/build-support/docker/store-path-to-layer.sh index 98c5b8cc2129..bcad9e83e06f 100755 --- a/nixpkgs/pkgs/build-support/docker/store-path-to-layer.sh +++ b/nixpkgs/pkgs/build-support/docker/store-path-to-layer.sh @@ -9,7 +9,9 @@ layerPath="./layers/$layerNumber" echo "Creating layer #$layerNumber for $@" mkdir -p "$layerPath" -tar --no-recursion -rf "$layerPath/layer.tar" /nix /nix/store +tar --no-recursion -rf "$layerPath/layer.tar" \ + --mtime="@$SOURCE_DATE_EPOCH" \ + --owner=0 --group=0 /nix /nix/store tar -rpf "$layerPath/layer.tar" --hard-dereference --sort=name \ --mtime="@$SOURCE_DATE_EPOCH" \ --owner=0 --group=0 "$@" diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd.nix b/nixpkgs/pkgs/build-support/kernel/make-initrd.nix index 7ad1affb65a3..7a5642e565de 100644 --- a/nixpkgs/pkgs/build-support/kernel/make-initrd.nix +++ b/nixpkgs/pkgs/build-support/kernel/make-initrd.nix @@ -16,10 +16,16 @@ , name ? "initrd" , compressor ? "gzip -9n" , prepend ? [] +, lib }: +let + # !!! Move this into a public lib function, it is probably useful for others + toValidStoreName = x: with builtins; + lib.concatStringsSep "-" (filter (x: !(isList x)) (split "[^a-zA-Z0-9_=.?-]+" x)); -stdenv.mkDerivation rec { +in stdenv.mkDerivation rec { inherit name; + builder = ./make-initrd.sh; makeUInitrd = stdenv.hostPlatform.platform.kernelTarget == "uImage"; @@ -36,8 +42,12 @@ stdenv.mkDerivation rec { # Note: we don't use closureInfo yet, as that won't build with nix-1.x. # See #36268. exportReferencesGraph = - map (x: [("closure-" + baseNameOf x.symlink) x.object]) contents; + lib.zipListsWith + (x: i: [("closure-${toValidStoreName (baseNameOf x.symlink)}-${toString i}") x.object]) + contents + (lib.range 0 (lib.length contents - 1)); pathsFromGraph = ./paths-from-graph.pl; inherit compressor prepend; } + diff --git a/nixpkgs/pkgs/build-support/nuke-references/builder.sh b/nixpkgs/pkgs/build-support/nuke-references/builder.sh index 02eac664d437..7da322032185 100644 --- a/nixpkgs/pkgs/build-support/nuke-references/builder.sh +++ b/nixpkgs/pkgs/build-support/nuke-references/builder.sh @@ -7,7 +7,7 @@ cat > $out/bin/nuke-refs <<EOF excludes="" while getopts e: o; do case "\$o" in - e) storeId=\$(echo "\$OPTARG" | sed -n "s|^$NIX_STORE/\\([a-z0-9]\{32\}\\)-.*|\1|p") + e) storeId=\$(echo "\$OPTARG" | $perl/bin/perl -ne "print \"\\\$1\" if m|^\Q$NIX_STORE\E/([a-z0-9]{32})-.*|") if [ -z "\$storeId" ]; then echo "-e argument must be a Nix store path" exit 1 @@ -20,7 +20,7 @@ shift \$((\$OPTIND-1)) for i in "\$@"; do if test ! -L "\$i" -a -f "\$i"; then - cat "\$i" | $perl/bin/perl -pe "s|$NIX_STORE/\$excludes[a-z0-9]{32}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" > "\$i.tmp" + cat "\$i" | $perl/bin/perl -pe "s|\Q$NIX_STORE\E/\$excludes[a-z0-9]{32}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" > "\$i.tmp" if test -x "\$i"; then chmod +x "\$i.tmp"; fi mv "\$i.tmp" "\$i" fi diff --git a/nixpkgs/pkgs/build-support/trivial-builders.nix b/nixpkgs/pkgs/build-support/trivial-builders.nix index f56ce7bb87d0..b66c1d9e4d15 100644 --- a/nixpkgs/pkgs/build-support/trivial-builders.nix +++ b/nixpkgs/pkgs/build-support/trivial-builders.nix @@ -107,10 +107,15 @@ rec { writeTextDir = name: text: writeTextFile {inherit name text; destination = "/${name}";}; /* - * Writes a text file to /nix/store/<store path> and marks the file as executable. + * Writes a text file to /nix/store/<store path> and marks the file as + * executable. + * + * If passed as a build input, will be used as a setup hook. This makes setup + * hooks more efficient to create: you don't need a derivation that copies + * them to $out/nix-support/setup-hook, instead you can use the file as is. * * Example: - * # Writes my-file to /nix/store/<store path>/bin/my-file and makes executable + * # Writes my-file to /nix/store/<store path> and makes executable * writeScript "my-file" * '' * Contents of File diff --git a/nixpkgs/pkgs/build-support/writers/default.nix b/nixpkgs/pkgs/build-support/writers/default.nix index 29a4bbad703e..ae7b42449fb3 100644 --- a/nixpkgs/pkgs/build-support/writers/default.nix +++ b/nixpkgs/pkgs/build-support/writers/default.nix @@ -24,6 +24,9 @@ rec { }) '' echo "#! $interpreter" > $out cat "$contentPath" >> $out + ${optionalString (check != "") '' + ${check} $out + ''} chmod +x $out ${optionalString (types.path.check nameOrPath) '' mv $out tmp |