summary refs log tree commit diff
path: root/pkgs/tools/filesystems/glusterfs/default.nix
diff options
context:
space:
mode:
authorNiklas Hambüchen <mail@nh2.me>2017-05-11 16:56:07 +0200
committerNiklas Hambüchen <mail@nh2.me>2017-05-19 16:56:30 +0200
commit85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7 (patch)
treecafc68f916d9070b280129a7fe40eb4f7a5d2122 /pkgs/tools/filesystems/glusterfs/default.nix
parent833acf9ff1aad07193c405e934d8c4982a45837f (diff)
downloadnixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar.gz
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar.bz2
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar.lz
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar.xz
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.tar.zst
nixpkgs-85f6ff48e1eea58fc728c4ffe4f35afe2a2e18b7.zip
glusterfs: Make commands that gluster calls work. Fixes #25620.
Done by setting PATH and PYTHONPATH appropriately.

Adds the following patches:

* One that removes hardcodes to /sbin, /usr/bin, etc.
  from gluster, so that programs like `lvm` and `xfs_info` can be
  called at runtime; see https://bugzilla.redhat.com/show_bug.cgi?id=1450546.
* One that fixes unsubstituted autoconf macros in paths (a problem
  in the 3.10 release); see https://bugzilla.redhat.com/show_bug.cgi?id=1450588.
* One that removes uses of the `find_library()` Python function that does
  not behave as expected in Python < 3.6 (and would not behave correctly
  even on 3.6 in nixpkgs due to #25763);
  see https://bugzilla.redhat.com/show_bug.cgi?id=1450593.

I think that all of these patches should be upstreamed.

Also adds tests to check that none of the Python based utilities
throw import errors, calling `--help` or equivalent on them.
Diffstat (limited to 'pkgs/tools/filesystems/glusterfs/default.nix')
-rw-r--r--pkgs/tools/filesystems/glusterfs/default.nix119
1 files changed, 115 insertions, 4 deletions
diff --git a/pkgs/tools/filesystems/glusterfs/default.nix b/pkgs/tools/filesystems/glusterfs/default.nix
index 6d6f0f3b1c8..de36606678a 100644
--- a/pkgs/tools/filesystems/glusterfs/default.nix
+++ b/pkgs/tools/filesystems/glusterfs/default.nix
@@ -1,31 +1,76 @@
 {stdenv, fetchurl, fuse, bison, flex_2_5_35, openssl, python2, ncurses, readline,
- autoconf, automake, libtool, pkgconfig, zlib, libaio, libxml2, acl, sqlite
- , liburcu, attr, makeWrapper, coreutils, gnused, gnugrep, which
+ autoconf, automake, libtool, pkgconfig, zlib, libaio, libxml2, acl, sqlite,
+ liburcu, attr, makeWrapper, coreutils, gnused, gnugrep, which, python2Packages,
+ openssh, gawk, findutils, utillinux, lvm2, btrfs-progs, e2fsprogs, xfsprogs, systemd,
+ rsync, glibc
 }:
 let
   s =
   rec {
     baseName="glusterfs";
+    # NOTE: On each glusterfs release, it should be checked if gluster added
+    #       new, or changed, Python scripts whose PYTHONPATH has to be set in
+    #       `postFixup` below, and whose runtime deps need to go into
+    #       `nativeBuildInputs`.
+    #       The command
+    #         find /nix/store/...-glusterfs-.../ -name '*.py' -executable
+    #       can help with finding new Python scripts.
     version = "3.10.1";
     name="${baseName}-${version}";
     url="https://github.com/gluster/glusterfs/archive/v${version}.tar.gz";
     sha256 = "0gmb3m98djljcycjggi1qv99ai6k4cvn2rqym2q9f58q8n8kdhh7";
   };
   buildInputs = [
-    fuse bison flex_2_5_35 openssl python2 ncurses readline
+    fuse bison flex_2_5_35 openssl ncurses readline
     autoconf automake libtool pkgconfig zlib libaio libxml2
     acl sqlite liburcu attr makeWrapper
+    (python2.withPackages (pkgs: [
+      pkgs.flask
+      pkgs.prettytable
+      pkgs.requests
+      pkgs.xattr
+    ]))
+    # NOTE: `python2` has to be *AFTER* the above `python2.withPackages`,
+    #       to ensure that the packages are available but the `toPythonPath`
+    #       shell function used in `postFixup` is also still available.
+    python2
   ];
   # Some of the headers reference acl
   propagatedBuildInputs = [
     acl
   ];
+  # Packages from which GlusterFS calls binaries at run-time from PATH,
+  # with comments on which commands are known to be called by it.
+  runtimePATHdeps = [
+    attr # getfattr setfattr
+    btrfs-progs # btrfs
+    coreutils # lots of commands in bash scripts
+    e2fsprogs # tune2fs
+    findutils # find
+    gawk # awk
+    glibc # getent
+    gnugrep # grep
+    gnused # sed
+    lvm2 # lvs
+    openssh # ssh
+    rsync # rsync, e.g. for geo-replication
+    systemd # systemctl
+    utillinux # mount umount
+    which # which
+    xfsprogs # xfs_info
+  ];
 in
 stdenv.mkDerivation
 rec {
   inherit (s) name version;
   inherit buildInputs propagatedBuildInputs;
 
+  patches = [
+    ./glusterfs-use-PATH-instead-of-hardcodes.patch
+    ./glusterfs-fix-unsubstituted-autoconf-macros.patch
+    ./glusterfs-python-remove-find_library.patch
+  ];
+
    # Note that the VERSION file is something that is present in release tarballs
    # but not in git tags (at least not as of writing in v3.10.1).
    # That's why we have to create it.
@@ -49,7 +94,73 @@ rec {
   postInstall = ''
     cp -r $out/$out/* $out
     rm -r $out/nix
-    wrapProgram $out/sbin/mount.glusterfs --set PATH "${stdenv.lib.makeBinPath [ coreutils gnused attr gnugrep which]}"
+    '';
+
+  postFixup = ''
+    # glusterd invokes `gluster` and other utilities when telling other glusterd nodes to run commands.
+    # For example for `peer_georep-sshkey` key generation, so `$out/bin` is needed in the PATH.
+    # It also invokes bash scripts like `gverify.sh`.
+    # It also invokes executable Python scripts in `$out/libexec/glusterfs`, which is why we set up PYTHONPATH accordingly.
+    # We set up the paths for the main entry point executables.
+
+    GLUSTER_PATH="${stdenv.lib.makeBinPath runtimePATHdeps}:$out/bin"
+    GLUSTER_PYTHONPATH="$(toPythonPath $out):$out/libexec/glusterfs"
+    GLUSTER_LD_LIBRARY_PATH="$out/lib"
+
+    wrapProgram $out/bin/glusterd --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    wrapProgram $out/bin/gluster --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    wrapProgram $out/sbin/mount.glusterfs --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+
+    # Set Python environment for the Python based utilities.
+    # It would be nice if there was a better way to do this, automatically for all of them.
+    # Also, this is brittle: If we forget a dependency or gluster adds a new one, things will break deep inside gluster.
+    # We should better try to get an explicit list of Python dependencies from gluster and ensure all of them are in the PYTHONPATH of all these python scripts.
+    # But at the time of writing (gluster 3.10), gluster only provides this in form of a gluster.spec file for RPM creation,
+    # and even that one is not complete (for example it doesn't mention the `flask` dependency).
+
+    wrapProgram $out/bin/gluster-eventsapi --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    wrapProgram $out/bin/gluster-georep-sshkey --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    wrapProgram $out/bin/gluster-mountbroker --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    wrapProgram $out/bin/glusterfind --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+
+    # Note that we only wrap the symlinks in $out/bin, not the actual executable scripts in $out/libexec/glusterfs.
+    # This is because those scripts use `__file__` in their program logic
+    # (see https://github.com/gluster/glusterfs/blob/v3.10.1/extras/cliutils/cliutils.py#L116)
+    # which would break if we changed the file name (which is what `wrapProgram` does).
+    # Luckily, `libexec` scripts are never supposed to be invoked straight from PATH,
+    # instead they are invoked directly from `gluster` or `glusterd`, which is why it is
+    # sufficient to set PYTHONPATH for those executables.
+
+    wrapProgram $out/share/glusterfs/scripts/eventsdash.py --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
+    '';
+
+  doInstallCheck = true;
+
+  # Below we run Python programs. That generates .pyc/.pyo files.
+  # By default they are indeterministic because such files contain time stamps
+  # (see https://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html).
+  # So we use the same environment variables as in
+  #   https://github.com/NixOS/nixpkgs/blob/249b34aadca7038207492f29142a3456d0cecec3/pkgs/development/interpreters/python/mk-python-derivation.nix#L61
+  # to make these files deterministic.
+  # A general solution to this problem might be brought by #25707.
+  DETERMINISTIC_BUILD = 1;
+  PYTHONHASHSEED = 0;
+
+  installCheckPhase = ''
+    # Tests that the above programs work without import errors.
+    # For testing it manually in a shell you may want to substitute `$out` with `$(dirname $(readlink -f $(which gluster)))/../`.
+    $out/bin/glusterd --help
+    # $out/bin/gluster help # can't do this because even `gluster help` tries to write to `/var/log/glusterfs/cli.log`
+    $out/bin/gluster-eventsapi --help
+    $out/bin/gluster-georep-sshkey --help
+    $out/bin/gluster-mountbroker --help
+    $out/bin/glusterfind --help
+    # gfid_to_path.py doesn't accept --help, and it requires different arguments
+    # (a dir as single argument) than the usage prints when stdin is not a TTY.
+    # The `echo ""` is just so that stdin is not a TTY even if you try this line
+    # on a real TTY for testing purposes.
+    echo "" | (mkdir -p nix-test-dir-for-gfid_to_path && touch b && $out/libexec/glusterfs/gfind_missing_files/gfid_to_path.py nix-test-dir-for-gfid_to_path)
+    $out/share/glusterfs/scripts/eventsdash.py --help
     '';
 
   src = fetchurl {