about summary refs log tree commit diff
path: root/pkgs/servers
diff options
context:
space:
mode:
authorsternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-03-20 23:45:47 +0100
committersternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-03-21 01:32:51 +0100
commitb77f1bc48a51a5019dc16c146665f98b38ff8857 (patch)
tree8e4e576c2c6f185224e434a4567dcc8e86db1720 /pkgs/servers
parent820a6336aec3cbbbf4e111a80097d0d1208243b5 (diff)
downloadnixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar.gz
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar.bz2
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar.lz
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar.xz
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.tar.zst
nixlib-b77f1bc48a51a5019dc16c146665f98b38ff8857.zip
inspircd: init at 3.9.0
Packaging inspircd is relatively straightforward, once we adapt to the
slightly strange Perl configure script and it's firm opinion that
$prefix/usr should exist.

Most complexity in this derivation stems from the following:

* inspircd has modules which users can load dynamically in the form of
  shared objects that link against other libraries for various tasks

* inspircd is licensed exclusively under the GPL version 2.

* Some of the libraries inspircd modules link against are GPL 2
  incompatible (GPL 3, ASL 2.0) and we therefore must not distribute
  these in binary form.

* Some modules combine GPL 2 code of inspircd and libc into a shared
  object and may not be redistributed in binary form depending on the
  license of the libc. Similarly for libc++.
  Open Question: Does the fact that we may build the inspircd binary, i.
  e. link against libc and libc++ imply that we can do this?
  https://docs.inspircd.org/packaging/ seems to imply this is not the
  case.

Thus we have some additional code which a) determines the set of modules
we should enable by default (the largest possible set as upstream
recommends it) and b) collects all applying licenses into meta.license.
Diffstat (limited to 'pkgs/servers')
-rw-r--r--pkgs/servers/irc/inspircd/default.nix218
1 files changed, 218 insertions, 0 deletions
diff --git a/pkgs/servers/irc/inspircd/default.nix b/pkgs/servers/irc/inspircd/default.nix
new file mode 100644
index 000000000000..f1df10514e6a
--- /dev/null
+++ b/pkgs/servers/irc/inspircd/default.nix
@@ -0,0 +1,218 @@
+let
+  # inspircd ships a few extra modules that users can load
+  # via configuration. Upstream thus recommends to ship as
+  # many of them as possible. There is however a problem:
+  # inspircd is licensed under the GPL version 2 only and
+  # some modules link libraries that are incompatible with
+  # the GPL 2. Therefore we can't provide them as binaries
+  # via our binary-caches, but users should still be able
+  # to override this package and build the incompatible
+  # modules themselves.
+  #
+  # This means for us we need to a) prevent hydra from
+  # building a module set with a GPL incompatibility
+  # and b) dynamically figure out the largest possible
+  # set of modules to use depending on stdenv, because
+  # the used libc needs to be compatible as well.
+  #
+  # For an overview of all modules and their licensing
+  # situation, see https://docs.inspircd.org/packaging/
+
+  # Predicate for checking license compatibility with
+  # GPLv2. Since this is _only_ used for libc compatibility
+  # checking, only whitelist licenses used by notable
+  # libcs in nixpkgs (musl and glibc).
+  compatible = lib: drv:
+    lib.any (lic: lic == drv.meta.license) [
+      lib.licenses.mit        # musl
+      lib.licenses.lgpl2Plus  # glibc
+    ];
+
+  # compatible if libc is compatible
+  libcModules = [
+    "regex_posix"
+    "sslrehashsignal"
+  ];
+
+  # compatible if libc++ is compatible
+  # TODO(sternenseemann):
+  # we could enable "regex_stdlib" automatically, but only if
+  # we are using libcxxStdenv which is compatible with GPLv2,
+  # since the gcc libstdc++ license is GPLv2-incompatible
+  libcxxModules = [
+    "regex_stdlib"
+  ];
+
+  compatibleModules = lib: stdenv: [
+    # GPLv2 compatible dependencies
+    "argon2"
+    "ldap"
+    "mysql"
+    "pgsql"
+    "regex_pcre"
+    "regex_re2"
+    "regex_tre"
+    "sqlite3"
+    "ssl_gnutls"
+  ] ++ lib.optionals (compatible lib stdenv.cc.libc) libcModules;
+
+in
+
+{ lib
+, stdenv
+, fetchFromGitHub
+, fetchpatch
+, perl
+, pkg-config
+, libargon2
+, openldap
+, postgresql
+, libmysqlclient
+, pcre
+, tre
+, re2
+, sqlite
+, gnutls
+, libmaxminddb
+, openssl
+, mbedtls
+# For a full list of module names, see https://docs.inspircd.org/packaging/
+, extraModules ? compatibleModules lib stdenv
+}:
+
+let
+  extras = {
+    # GPLv2 compatible
+    argon2 = [
+      (libargon2 // {
+        meta = libargon2.meta // {
+          # use libargon2 as CC0 since ASL20 is GPLv2-incompatible
+          # updating this here is important that meta.license is accurate
+          license = lib.licenses.cc0;
+        };
+      })
+    ];
+    ldap            = [ openldap ];
+    mysql           = [ libmysqlclient ];
+    pgsql           = [ postgresql ];
+    regex_pcre      = [ pcre ];
+    regex_re2       = [ re2 ];
+    regex_tre       = [ tre ];
+    sqlite3         = [ sqlite ];
+    ssl_gnutls      = [ gnutls ];
+    # depends on stdenv.cc.libc
+    regex_posix     = [];
+    sslrehashsignal = [];
+    # depends on used libc++
+    regex_stdlib    = [];
+    # GPLv2 incompatible
+    geo_maxmind     = [ libmaxminddb ];
+    ssl_mbedtls     = [ mbedtls ];
+    ssl_openssl     = [ openssl ];
+  };
+
+  # buildInputs necessary for the enabled extraModules
+  extraInputs = lib.concatMap
+    (m: extras."${m}" or (builtins.throw "Unknown extra module ${m}"))
+    extraModules;
+
+  # if true, we can't provide a binary version of this
+  # package without violating the GPL 2
+  gpl2Conflict =
+    let
+      allowed = compatibleModules lib stdenv;
+    in
+      !lib.all (lib.flip lib.elem allowed) extraModules;
+
+  # return list of the license(s) of the given derivation
+  getLicenses = drv:
+    let
+      lics = drv.meta.license or [];
+    in
+      if lib.isAttrs lics || lib.isString lics
+      then [ lics ]
+      else lics;
+
+  # Whether any member of list1 is also member of list2, i. e. set intersection.
+  anyMembers = list1: list2:
+    lib.any (m1: lib.elem m1 list2) list1;
+
+in
+
+stdenv.mkDerivation rec {
+  pname = "inspircd";
+  version = "3.9.0";
+
+  src = fetchFromGitHub {
+    owner = pname;
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "0x3paasf4ynx4ddky2nq613vyirbhfnxzkjq148k7154pz3q426s";
+  };
+
+  patches = [
+    # Remove at next release, makes --prefix and --system work together
+    (fetchpatch {
+      url = "https://github.com/inspircd/inspircd/commit/b378b5087b41f72a1624ebb58990180e0b0140aa.patch";
+      sha256 = "0c0fmhjbkfh2r1cmjrm5d4whcignwsyi6kwkhmcvqy9mv99pj2ir";
+    })
+  ];
+
+  nativeBuildInputs = [
+    perl
+    pkg-config
+  ];
+  buildInputs = extraInputs;
+
+  preConfigure = ''
+    patchShebangs configure make/*.pl
+    # configure is executed twice, once to set the extras
+    # to use and once to do the Makefile setup
+    ./configure --enable-extras \
+      ${lib.escapeShellArg (lib.concatStringsSep " " extraModules)}
+  '';
+
+  configureFlags = [
+    "--disable-auto-extras"
+    "--distribution-label" "nixpkgs${version}"
+    "--system"
+    "--uid" "0"
+    "--gid" "0"
+    "--prefix" (placeholder "out")
+  ];
+
+  postInstall = ''
+    # installs to $out/usr by default unfortunately
+    mv "$out/usr/lib" "$out/lib"
+    mv "$out/usr/sbin" "$out/bin"
+    mv "$out/usr/share" "$out/share"
+    rm -r "$out/usr"
+    rm -r "$out/var" # only empty directories
+    rm -r "$out/etc" # only contains documentation
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = {
+    description = "A modular C++ IRC server";
+    license = [ lib.licenses.gpl2Only ]
+      ++ lib.concatMap getLicenses extraInputs
+      ++ lib.optionals (anyMembers extraModules libcModules) (getLicenses stdenv.cc.libc)
+      # FIXME(sternenseemann): get license of used lib(std)c++ somehow
+      ++ lib.optional (anyMembers extraModules libcxxModules) "Unknown"
+      # Hack: Definitely prevent a hydra from building this package on
+      # a GPL 2 incompatibility even if it is not in a top-level attribute,
+      # but pulled in indirectly somehow.
+      ++ lib.optional gpl2Conflict lib.licenses.unfree;
+    maintainers = [ lib.maintainers.sternenseemann ];
+    # windows is theoretically possible, but requires extra work
+    # which I am not willing to do and can't test.
+    # https://github.com/inspircd/inspircd/blob/master/win/README.txt
+    platforms = lib.platforms.unix;
+    homepage = "https://www.inspircd.org/";
+  } // lib.optionalAttrs gpl2Conflict {
+    # make sure we never distribute a GPLv2-violating module
+    # in binary form. They can be built locally of course.
+    hydraPlatforms = [];
+  };
+}