Unverified Commit b0a64354 authored by Sandro Jäckel's avatar Sandro Jäckel Committed by GitHub
Browse files

nixos/prosody: add config check option (#260551)

parents f8a31163 0a92661e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -141,6 +141,8 @@

- `services.clamsmtp` is unmaintained and was removed from Nixpkgs.

- `prosody` gained a config check option named `services.prosody.checkConfig` which runs `prosodyctl check config` and is turned on by default.

- `services.dependency-track` removed its configuration of the JVM heap size. This lets the JVM choose its maximum heap size automatically, which should work much better in practice for most users. For deployments on systems with little RAM, it may now be necessary to manually configure a maximum heap size using  {option}`services.dependency-track.javaArgs`.

- `services.dnscrypt-proxy2` gains a `package` option to specify dnscrypt-proxy package to use.
+341 −354
Original line number Diff line number Diff line
@@ -9,12 +9,8 @@ with lib;
let
  cfg = config.services.prosody;

  sslOpts =
    { ... }:
    {

  sslOpts = _: {
    options = {

      key = mkOption {
        type = types.path;
        description = "Path to the key file.";
@@ -31,7 +27,6 @@ let
        default = { };
        description = "Extra SSL configuration options.";
      };

    };
  };

@@ -301,9 +296,7 @@ let
    };
  '';

  mucOpts =
    { ... }:
    {
  mucOpts = _: {
    options = {
      domain = mkOption {
        type = types.str;
@@ -373,7 +366,7 @@ let
        default = false;
        description = ''
          Add module allowners, any user in chat is able to
            kick other. Usefull in jitsi-meet to kick ghosts.
          kick other. Useful in jitsi-meet to kick ghosts.
        '';
      };
      vcard_muc = mkOption {
@@ -430,9 +423,7 @@ let
    };
  };

  uploadHttpOpts =
    { ... }:
    {
  uploadHttpOpts = _: {
    options = {
      domain = mkOption {
        type = types.nullOr types.str;
@@ -468,9 +459,7 @@ let
    };
  };

  httpFileShareOpts =
    { ... }:
    {
  httpFileShareOpts = _: {
    freeformType =
      with types;
      let
@@ -491,12 +480,8 @@ let
    };
  };

  vHostOpts =
    { ... }:
    {

  vHostOpts = _: {
    options = {

      # TODO: require attribute
      domain = mkOption {
        type = types.str;
@@ -520,27 +505,140 @@ let
        default = "";
        description = "Additional virtual host specific configuration";
      };
    };
  };

  configFile =
    let
      httpDiscoItems =
        optional (cfg.uploadHttp != null) {
          url = cfg.uploadHttp.domain;
          description = "HTTP upload endpoint";
        }
        ++ optional (cfg.httpFileShare != null) {
          url = cfg.httpFileShare.domain;
          description = "HTTP file share endpoint";
        };
      mucDiscoItems = builtins.foldl' (
        acc: muc:
        [
          {
            url = muc.domain;
            description = "${muc.domain} MUC endpoint";
          }
        ]
        ++ acc
      ) [ ] cfg.muc;
      discoItems = cfg.disco_items ++ httpDiscoItems ++ mucDiscoItems;
    in
    pkgs.writeText "prosody.cfg.lua" ''
      pidfile = "/run/prosody/prosody.pid"

      log = ${cfg.log}

      data_path = "${cfg.dataDir}"
      plugin_paths = {
        ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.extraPluginPaths)}
      }

      ${optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl)}

      admins = ${toLua cfg.admins}

      modules_enabled = {

        ${lib.concatStringsSep "\n  " (
          lib.mapAttrsToList (name: val: optionalString val "${toLua name};") cfg.modules
        )}
        ${lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.package.communityModules)}
        ${lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.extraModules)}
      };

in
      disco_items = {
      ${lib.concatStringsSep "\n" (builtins.map (x: ''{ "${x.url}", "${x.description}"};'') discoItems)}
      };

{
      allow_registration = ${toLua cfg.allowRegistration}

  ###### interface
      c2s_require_encryption = ${toLua cfg.c2sRequireEncryption}

  options = {
      s2s_require_encryption = ${toLua cfg.s2sRequireEncryption}
      s2s_secure_auth = ${toLua cfg.s2sSecureAuth}
      s2s_insecure_domains = ${toLua cfg.s2sInsecureDomains}
      s2s_secure_domains = ${toLua cfg.s2sSecureDomains}

    services.prosody = {
      authentication = ${toLua cfg.authentication}

      http_interfaces = ${toLua cfg.httpInterfaces}
      https_interfaces = ${toLua cfg.httpsInterfaces}

      http_ports = ${toLua cfg.httpPorts}
      https_ports = ${toLua cfg.httpsPorts}

      ${cfg.extraConfig}

      ${lib.concatMapStrings (muc: ''
        Component ${toLua muc.domain} "muc"
            modules_enabled = { "muc_mam"; ${optionalString muc.vcard_muc ''"vcard_muc";''} ${optionalString muc.allowners_muc ''"muc_allowners";''}  }
            name = ${toLua muc.name}
            restrict_room_creation = ${toLua muc.restrictRoomCreation}
            max_history_messages = ${toLua muc.maxHistoryMessages}
            muc_room_locking = ${toLua muc.roomLocking}
            muc_room_lock_timeout = ${toLua muc.roomLockTimeout}
            muc_tombstones = ${toLua muc.tombstones}
            muc_tombstone_expiry = ${toLua muc.tombstoneExpiry}
            muc_room_default_public = ${toLua muc.roomDefaultPublic}
            muc_room_default_members_only = ${toLua muc.roomDefaultMembersOnly}
            muc_room_default_moderated = ${toLua muc.roomDefaultModerated}
            muc_room_default_public_jids = ${toLua muc.roomDefaultPublicJids}
            muc_room_default_change_subject = ${toLua muc.roomDefaultChangeSubject}
            muc_room_default_history_length = ${toLua muc.roomDefaultHistoryLength}
            muc_room_default_language = ${toLua muc.roomDefaultLanguage}
            ${muc.extraConfig}
      '') cfg.muc}

      ${lib.optionalString (cfg.uploadHttp != null) ''
        Component ${toLua cfg.uploadHttp.domain} "http_upload"
            http_upload_file_size_limit = ${cfg.uploadHttp.uploadFileSizeLimit}
            http_upload_expire_after = ${cfg.uploadHttp.uploadExpireAfter}
            ${lib.optionalString (
              cfg.uploadHttp.userQuota != null
            ) "http_upload_quota = ${toLua cfg.uploadHttp.userQuota}"}
            http_upload_path = ${toLua cfg.uploadHttp.httpUploadPath}
      ''}

      ${lib.optionalString (cfg.httpFileShare != null) ''
        Component ${toLua cfg.httpFileShare.domain} "http_file_share"
        ${settingsToLua "  http_file_share_" (cfg.httpFileShare // { domain = null; })}
      ''}

      ${lib.concatStringsSep "\n" (
        lib.mapAttrsToList (n: v: ''
          VirtualHost "${v.domain}"
            enabled = ${boolToString v.enabled};
            ${optionalString (v.ssl != null) (createSSLOptsStr v.ssl)}
            ${v.extraConfig}
        '') cfg.virtualHosts
      )}
    '';

in
{
  options = {
    services.prosody = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = "Whether to enable the prosody server";
      };

      checkConfig = mkOption {
        type = types.bool;
        default = true;
        example = false;
        description = "Check the configuration file with `prosodyctl check config`";
      };

      xmppComplianceSuite = mkOption {
        type = types.bool;
        default = true;
@@ -818,14 +916,10 @@ in
          }
        '';
      };

    };
  };

  ###### implementation

  config = mkIf cfg.enable {

    assertions =
      let
        genericErrMsg = ''
@@ -860,125 +954,19 @@ in

    environment.systemPackages = [ cfg.package ];

    environment.etc."prosody/prosody.cfg.lua".text =
      let
        httpDiscoItems =
          optional (cfg.uploadHttp != null) {
            url = cfg.uploadHttp.domain;
            description = "HTTP upload endpoint";
          }
          ++ optional (cfg.httpFileShare != null) {
            url = cfg.httpFileShare.domain;
            description = "HTTP file share endpoint";
          };
        mucDiscoItems = builtins.foldl' (
          acc: muc:
          [
    environment.etc."prosody/prosody.cfg.lua".source =
      if cfg.checkConfig then
        pkgs.runCommandLocal "prosody.cfg.lua-checked"
          {
              url = muc.domain;
              description = "${muc.domain} MUC endpoint";
            nativeBuildInputs = [ cfg.package ];
          }
          ]
          ++ acc
        ) [ ] cfg.muc;
        discoItems = cfg.disco_items ++ httpDiscoItems ++ mucDiscoItems;
      in
          ''

        pidfile = "/run/prosody/prosody.pid"

        log = ${cfg.log}

        data_path = "${cfg.dataDir}"
        plugin_paths = {
          ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.extraPluginPaths)}
        }

        ${optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl)}

        admins = ${toLua cfg.admins}

        modules_enabled = {

          ${lib.concatStringsSep "\n  " (
            lib.mapAttrsToList (name: val: optionalString val "${toLua name};") cfg.modules
          )}
          ${lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.package.communityModules)}
          ${lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.extraModules)}
        };

        disco_items = {
        ${lib.concatStringsSep "\n" (builtins.map (x: ''{ "${x.url}", "${x.description}"};'') discoItems)}
        };

        allow_registration = ${toLua cfg.allowRegistration}

        c2s_require_encryption = ${toLua cfg.c2sRequireEncryption}

        s2s_require_encryption = ${toLua cfg.s2sRequireEncryption}

        s2s_secure_auth = ${toLua cfg.s2sSecureAuth}

        s2s_insecure_domains = ${toLua cfg.s2sInsecureDomains}

        s2s_secure_domains = ${toLua cfg.s2sSecureDomains}

        authentication = ${toLua cfg.authentication}

        http_interfaces = ${toLua cfg.httpInterfaces}

        https_interfaces = ${toLua cfg.httpsInterfaces}

        http_ports = ${toLua cfg.httpPorts}

        https_ports = ${toLua cfg.httpsPorts}

        ${cfg.extraConfig}

        ${lib.concatMapStrings (muc: ''
          Component ${toLua muc.domain} "muc"
              modules_enabled = { "muc_mam"; ${optionalString muc.vcard_muc ''"vcard_muc";''} ${optionalString muc.allowners_muc ''"muc_allowners";''}  }
              name = ${toLua muc.name}
              restrict_room_creation = ${toLua muc.restrictRoomCreation}
              max_history_messages = ${toLua muc.maxHistoryMessages}
              muc_room_locking = ${toLua muc.roomLocking}
              muc_room_lock_timeout = ${toLua muc.roomLockTimeout}
              muc_tombstones = ${toLua muc.tombstones}
              muc_tombstone_expiry = ${toLua muc.tombstoneExpiry}
              muc_room_default_public = ${toLua muc.roomDefaultPublic}
              muc_room_default_members_only = ${toLua muc.roomDefaultMembersOnly}
              muc_room_default_moderated = ${toLua muc.roomDefaultModerated}
              muc_room_default_public_jids = ${toLua muc.roomDefaultPublicJids}
              muc_room_default_change_subject = ${toLua muc.roomDefaultChangeSubject}
              muc_room_default_history_length = ${toLua muc.roomDefaultHistoryLength}
              muc_room_default_language = ${toLua muc.roomDefaultLanguage}
              ${muc.extraConfig}
        '') cfg.muc}

        ${lib.optionalString (cfg.uploadHttp != null) ''
          Component ${toLua cfg.uploadHttp.domain} "http_upload"
              http_upload_file_size_limit = ${cfg.uploadHttp.uploadFileSizeLimit}
              http_upload_expire_after = ${cfg.uploadHttp.uploadExpireAfter}
              ${lib.optionalString (
                cfg.uploadHttp.userQuota != null
              ) "http_upload_quota = ${toLua cfg.uploadHttp.userQuota}"}
              http_upload_path = ${toLua cfg.uploadHttp.httpUploadPath}
        ''}

        ${lib.optionalString (cfg.httpFileShare != null) ''
          Component ${toLua cfg.httpFileShare.domain} "http_file_share"
          ${settingsToLua "  http_file_share_" (cfg.httpFileShare // { domain = null; })}
        ''}

        ${lib.concatStringsSep "\n" (
          lib.mapAttrsToList (n: v: ''
            VirtualHost "${v.domain}"
              enabled = ${boolToString v.enabled};
              ${optionalString (v.ssl != null) (createSSLOptsStr v.ssl)}
              ${v.extraConfig}
          '') cfg.virtualHosts
        )}
      '';
            cp ${configFile} prosody.cfg.lua
            prosodyctl --config ./prosody.cfg.lua check config
            touch $out
          ''
      else
        configFile;

    users.users.prosody = mkIf (cfg.user == "prosody") {
      uid = config.ids.uids.prosody;
@@ -1025,7 +1013,6 @@ in
        })
      ];
    };

  };

  meta.doc = ./prosody.md;