biome: 1.9.2 -> 1.9.3
[NixPkgs.git] / pkgs / tools / filesystems / glusterfs / default.nix
blob636a4520ea56f29dabdbe20d59970c7484b4d7cd
1 {lib, stdenv, fetchFromGitHub, fuse, bison, flex, openssl, python3, ncurses, readline,
2  autoconf, automake, libtool, pkg-config, zlib, libaio, libxml2, acl, sqlite,
3  liburcu, liburing, attr, makeWrapper, coreutils, gnused, gnugrep, which,
4  openssh, gawk, findutils, util-linux, lvm2, btrfs-progs, e2fsprogs, xfsprogs, systemd,
5  rsync, getent, rpcsvc-proto, libtirpc, gperftools, nixosTests
6 }:
7 let
8   # NOTE: On each glusterfs release, it should be checked if gluster added
9   #       new, or changed, Python scripts whose PYTHONPATH has to be set in
10   #       `postFixup` below, and whose runtime deps need to go into
11   #       `nativeBuildInputs`.
12   #       The command
13   #         find /nix/store/...-glusterfs-.../ -name '*.py' -executable
14   #       can help with finding new Python scripts.
16   buildInputs = [
17     fuse openssl ncurses readline
18     zlib libaio libxml2
19     acl sqlite liburcu attr util-linux libtirpc gperftools
20     liburing
21     (python3.withPackages (pkgs: [
22       pkgs.flask
23       pkgs.prettytable
24       pkgs.requests
25       pkgs.pyxattr
26     ]))
27     # NOTE: `python3` has to be *AFTER* the above `python3.withPackages`,
28     #       to ensure that the packages are available but the `toPythonPath`
29     #       shell function used in `postFixup` is also still available.
30     python3
31   ];
32   # Some of the headers reference acl
33   propagatedBuildInputs = [
34     acl
35   ];
36   # Packages from which GlusterFS calls binaries at run-time from PATH,
37   # with comments on which commands are known to be called by it.
38   runtimePATHdeps = [
39     attr # getfattr setfattr
40     btrfs-progs # btrfs
41     coreutils # lots of commands in bash scripts
42     e2fsprogs # tune2fs
43     findutils # find
44     gawk # awk
45     getent # getent
46     gnugrep # grep
47     gnused # sed
48     lvm2 # lvs
49     openssh # ssh
50     rsync # rsync, e.g. for geo-replication
51     systemd # systemctl
52     util-linux # mount umount
53     which # which
54     xfsprogs # xfs_info
55   ];
56 in stdenv.mkDerivation rec {
57   pname = "glusterfs";
58   version = "11.1";
60   src = fetchFromGitHub {
61     owner = "gluster";
62     repo = pname;
63     rev = "v${version}";
64     sha256 = "sha256-ZClMfozeFO3266fkuCSV04QwpZaYa8B0uq2lTPEN2rQ=";
65   };
66   inherit buildInputs propagatedBuildInputs;
68   patches = [
69     # Upstream invokes `openssl version -d` to derive the canonical system path
70     # for certificates, which resolves to a nix store path, so this patch
71     # statically sets the configure.ac value. There's probably a less-brittle
72     # way to do this! (this will likely fail on a version bump)
73     # References:
74     # - https://github.com/gluster/glusterfs/issues/3234
75     # - https://github.com/gluster/glusterfs/commit/a7dc43f533ad4b8ff68bf57704fefc614da65493
76     ./ssl_cert_path.patch
77   ];
79   postPatch = ''
80     sed -e '/chmod u+s/d' -i contrib/fuse-util/Makefile.am
81     substituteInPlace libglusterfs/src/glusterfs/lvm-defaults.h \
82       --replace-fail '/sbin/' '${lvm2}/bin/'
83     substituteInPlace libglusterfs/src/glusterfs/compat.h \
84       --replace-fail '/bin/umount' '${util-linux}/bin/umount'
85     substituteInPlace contrib/fuse-lib/mount-gluster-compat.h \
86       --replace-fail '/bin/mount' '${util-linux}/bin/mount'
87     # use local up to date m4 files to ensure the correct python version is detected
88     substituteInPlace autogen.sh \
89       --replace-fail '$ACLOCAL -I ./contrib/aclocal' '$ACLOCAL'
90   '';
92   # Note that the VERSION file is something that is present in release tarballs
93   # but not in git tags (at least not as of writing in v3.10.1).
94   # That's why we have to create it.
95   # Without this, gluster (at least 3.10.1) will fail very late and cryptically,
96   # for example when setting up geo-replication, with a message like
97   #   Staging of operation 'Volume Geo-replication Create' failed on localhost : Unable to fetch master volume details. Please check the master cluster and master volume.
98   # What happens here is that the gverify.sh script tries to compare the versions,
99   # but fails when the version is empty.
100   # See upstream GlusterFS bug https://bugzilla.redhat.com/show_bug.cgi?id=1452705
101   preConfigure = ''
102     patchShebangs build-aux/pkg-version
103     echo "v${version}" > VERSION
104     ./autogen.sh
105     export PYTHON=${python3}/bin/python
106   '';
108   configureFlags = [
109     "--localstatedir=/var"
110   ];
112   nativeBuildInputs = [ autoconf automake libtool pkg-config bison flex makeWrapper rpcsvc-proto ];
114   makeFlags = [ "DESTDIR=$(out)" ];
116   enableParallelBuilding = true;
118   postInstall = ''
119     cp -r $out/$out/* $out
120     rm -r $out/nix
121   '';
123   postFixup = ''
124     # glusterd invokes `gluster` and other utilities when telling other glusterd nodes to run commands.
125     # For example for `peer_georep-sshkey` key generation, so `$out/bin` is needed in the PATH.
126     # It also invokes bash scripts like `gverify.sh`.
127     # It also invokes executable Python scripts in `$out/libexec/glusterfs`, which is why we set up PYTHONPATH accordingly.
128     # We set up the paths for the main entry point executables.
130     GLUSTER_PATH="${lib.makeBinPath runtimePATHdeps}:$out/bin"
131     GLUSTER_PYTHONPATH="$(toPythonPath $out):$out/libexec/glusterfs"
132     GLUSTER_LD_LIBRARY_PATH="$out/lib"
134     wrapProgram $out/bin/glusterd --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
135     wrapProgram $out/bin/gluster --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
136     wrapProgram $out/sbin/mount.glusterfs --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
138     # Set Python environment for the Python based utilities.
139     # It would be nice if there was a better way to do this, automatically for all of them.
140     # Also, this is brittle: If we forget a dependency or gluster adds a new one, things will break deep inside gluster.
141     # 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.
142     # But at the time of writing (gluster 3.10), gluster only provides this in form of a gluster.spec file for RPM creation,
143     # and even that one is not complete (for example it doesn't mention the `flask` dependency).
145     wrapProgram $out/bin/gluster-eventsapi --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
146     wrapProgram $out/bin/gluster-georep-sshkey --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
147     wrapProgram $out/bin/gluster-mountbroker --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
148     wrapProgram $out/bin/glusterfind --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
150     # Note that we only wrap the symlinks in $out/bin, not the actual executable scripts in $out/libexec/glusterfs.
151     # This is because those scripts use `__file__` in their program logic
152     # (see https://github.com/gluster/glusterfs/blob/v3.10.1/extras/cliutils/cliutils.py#L116)
153     # which would break if we changed the file name (which is what `wrapProgram` does).
154     # Luckily, `libexec` scripts are never supposed to be invoked straight from PATH,
155     # instead they are invoked directly from `gluster` or `glusterd`, which is why it is
156     # sufficient to set PYTHONPATH for those executables.
157     #
158     # Exceptions to these rules are the `glusterfind` `brickfind.py` and `changelog.py`
159     # crawlers, which are directly invoked on other gluster nodes using a remote SSH command
160     # issues by `glusterfind`.
162     wrapProgram $out/share/glusterfs/scripts/eventsdash.py --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
163     wrapProgram $out/libexec/glusterfs/glusterfind/brickfind.py --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
164     wrapProgram $out/libexec/glusterfs/glusterfind/changelog.py --set PATH "$GLUSTER_PATH" --set PYTHONPATH "$GLUSTER_PYTHONPATH" --set LD_LIBRARY_PATH "$GLUSTER_LD_LIBRARY_PATH"
165   '';
167   doInstallCheck = true;
169   # Below we run Python programs. That generates .pyc/.pyo files.
170   # By default they are indeterministic because such files contain time stamps
171   # (see https://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html).
172   # So we use the same environment variables as in
173   #   https://github.com/NixOS/nixpkgs/blob/249b34aadca7038207492f29142a3456d0cecec3/pkgs/development/interpreters/python/mk-python-derivation.nix#L61
174   # to make these files deterministic.
175   # A general solution to this problem might be brought by #25707.
176   DETERMINISTIC_BUILD = 1;
177   PYTHONHASHSEED = 0;
179   installCheckPhase = ''
180     # Tests that the above programs work without import errors.
181     # For testing it manually in a shell you may want to substitute `$out` with `$(dirname $(readlink -f $(which gluster)))/../`.
182     $out/bin/glusterd --help
183     # $out/bin/gluster help # can't do this because even `gluster help` tries to write to `/var/log/glusterfs/cli.log`
184     $out/bin/gluster-eventsapi --help
185     $out/bin/gluster-georep-sshkey --help
186     $out/bin/gluster-mountbroker --help
187     $out/bin/glusterfind --help
188     # gfid_to_path.py doesn't accept --help, and it requires different arguments
189     # (a dir as single argument) than the usage prints when stdin is not a TTY.
190     # The `echo ""` is just so that stdin is not a TTY even if you try this line
191     # on a real TTY for testing purposes.
192     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)
193     $out/share/glusterfs/scripts/eventsdash.py --help
195     # this gets falsely loaded as module by glusterfind
196     rm -r $out/bin/conf.py
197   '';
199   passthru.tests = {
200     glusterfs = nixosTests.glusterfs;
201   };
203   meta = with lib; {
204     description = "Distributed storage system";
205     homepage = "https://www.gluster.org";
206     license = licenses.lgpl3Plus; # dual licese: choice of lgpl3Plus or gpl2
207     maintainers = [ maintainers.raskin ];
208     platforms = with platforms; linux ++ freebsd;
209   };