summaryrefslogtreecommitdiff
path: root/module
diff options
context:
space:
mode:
authorParthiv Seetharaman <pachum99@myrdd.info>2022-03-13 01:31:05 +0000
committerParthiv Seetharaman <pachum99@myrdd.info>2022-03-13 01:31:05 +0000
commitbcfc0748e3c4ab71466662c8f217537f7d55ff6e (patch)
tree88f7bbca39ee6bfbef508cdf677b7ff031ecdcfa /module
parentcc70149fc40ef67ee8b90a039ba388b3ae82eb82 (diff)
parent125aeaa50baf9cd0a40ece816760081eb594c51e (diff)
Merge branch 'allow-more-modules' into 'main'
modules: allow for more modules to be added See merge request coffeetables/nix-matrix-appservices!5
Diffstat (limited to 'module')
-rw-r--r--module/as-formats.nix160
-rw-r--r--module/as-options.nix144
-rw-r--r--module/default.nix180
3 files changed, 0 insertions, 484 deletions
diff --git a/module/as-formats.nix b/module/as-formats.nix
deleted file mode 100644
index fa7a4cf..0000000
--- a/module/as-formats.nix
+++ /dev/null
@@ -1,160 +0,0 @@
-{ name, systemConfig, asConfig, lib, pkgs, ... }:
-
-with lib;
-let
- inherit (systemConfig.services.matrix-appservices)
- homeserverURL
- homeserverDomain;
- package = asConfig.package;
- pname = getName package;
- command = "${package}/bin/${pname}";
-
- mautrix = {
- startupScript = ''
- ${command} --config=$SETTINGS_FILE \
- --registration=$REGISTRATION_FILE
- '';
-
- settings = {
- homeserver = {
- address = homeserverURL;
- domain = homeserverDomain;
- };
-
- appservice = with asConfig; {
- address = "http://${host}:${toString port}";
-
- hostname = host;
- inherit port;
-
- state_store_path = "$DIR/mx-state.json";
- # mautrix stores the registration tokens in the config file
- as_token = "$AS_TOKEN";
- hs_token = "$HS_TOKEN";
- };
-
- bridge = {
- username_template = "${name}_{userid}";
- permissions = {
- ${homeserverDomain} = "user";
- };
- };
- };
- };
-
-in
-{
- other = {
- description = ''
- No defaults will be set.
- '';
- };
-
- matrix-appservice = {
- startupScript = ''
- ${command} \
- --config=$SETTINGS_FILE \
- --port=$(echo ${asConfig.listenAddress} | sed 's/.*://') \
- --file=$REGISTRATION_FILE
- '';
-
- description = ''
- For bridges based on the matrix-appservice-bridge library. The settings for these
- bridges are NOT configured automatically, because of the various differences
- between them.
- '';
- };
-
- mx-puppet = {
- startupScript = ''
- ${command} \
- --config=$SETTINGS_FILE \
- --registration-file=$REGISTRATION_FILE
- '';
-
- registrationData =
- let
- # mx-puppet virtual users are always created based on the package name
- botName = removePrefix "mx-puppet-" pname;
- in
- {
- id = "${botName}-puppet";
- sender_localpart = "_${botName}puppet_bot";
- protocols = [ ];
- namespaces = {
- rooms = [ ];
- users = [
- {
- regex = "@_${botName}puppet_.*:${homeserverDomain}";
- exclusive = true;
- }
- ];
- aliases = [
- {
- regex = "#_${botName}puppet_.*:${homeserverDomain}";
- exclusive = true;
- }
- ];
- };
- };
-
- settings = {
- bridge = {
- inherit (asConfig) port;
- bindAddress = asConfig.host;
- domain = homeserverDomain;
- homeserverUrl = homeserverURL;
- };
- database.filename = "$DIR/database.db";
- provisioning.whitelist = [ "@.*:${homeserverDomain}" ];
- relay.whitelist = [ "@.*:${homeserverDomain}" ];
- selfService.whitelist = [ "@.*:${homeserverDomain}" ];
- logging = {
- lineDateFormat = "";
- files = [ ];
- };
- };
-
- serviceConfig.WorkingDirectory =
- "${package}/lib/node_modules/${pname}";
-
- description = ''
- For bridges based on the mx-puppet-bridge library. The settings will be
- configured to use a sqlite database. Make sure to override database.filename,
- if you plan to use another database.
- '';
-
- };
-
- mautrix-go = {
- inherit (mautrix) startupScript;
-
- settings = recursiveUpdate mautrix.settings {
- bridge.username_template = "${name}_{{.}}";
- appservice.database = {
- type = "sqlite3";
- uri = "$DIR/database.db";
- };
- };
-
- description = ''
- The settings are configured to use a sqlite database. The startupScript will
- create a new config file on every run to set the tokens, because mautrix
- requires them to be in the config file.
- '';
- };
-
- mautrix-python = {
- settings = recursiveUpdate mautrix.settings {
- appservice.database = "sqlite:///$DIR/database.db";
- };
-
- startupScript = optionalString (package ? alembic)
- "${package.alembic}/bin/alembic -x config=$SETTINGS_FILE upgrade head\n"
- + mautrix.startupScript;
- description = ''
- Same properties as mautrix-go. This will also upgrade the database on every run
- '';
- };
-
-}
diff --git a/module/as-options.nix b/module/as-options.nix
deleted file mode 100644
index 2afbbbf..0000000
--- a/module/as-options.nix
+++ /dev/null
@@ -1,144 +0,0 @@
-{ systemConfig, lib, pkgs, ... }:
-with lib;
-types.submodule ({ config, name, ... }:
- let
- inherit (systemConfig.services.matrix-appservices)
- homeserverDomain;
-
- asFormats = (import ./as-formats.nix) {
- inherit name lib pkgs systemConfig;
- asConfig = config;
- };
- asFormat = asFormats.${config.format};
- settingsFormat = pkgs.formats.json { };
- in
- {
- options = rec {
-
- format = mkOption {
- type = types.enum (mapAttrsToList (n: _: n) asFormats);
- default = "other";
- description = ''
- Format of the appservice, used to set option defaults for appservice.
- This is usually determined by the library the appservice is based on.
-
- Below are descriptions for each format
-
- '' + (concatStringsSep "\n" (mapAttrsToList
- (n: v: "${n}: ${v.description}")
- asFormats));
- };
-
- package = mkOption {
- type = types.nullOr types.package;
- default = null;
- example = "pkgs.mautrix-whatsapp";
- description = ''
- The package for the appservice. Used by formats except 'other'.
- This is unecessary if startupScript is set.
- '';
- };
-
- settings = mkOption rec {
- type = settingsFormat.type;
- apply = recursiveUpdate default;
- default = asFormat.settings or { };
- defaultText = "Format will attempt to configure database and allow homeserver users";
- example = literalExpression ''
- {
- bridge = {
- domain = "public-domain.tld";
- homeserverUrl = "http://public-domain.tld:8008";
- };
- }
- '';
- description = ''
- Appservice configuration as a Nix attribute set.
- All environment variables will be substituted.
- Including:
- - $DIR which refers to the appservice's data directory.
- - $AS_TOKEN, $HS_TOKEN which refers to the Appservice and
- Homeserver registration tokens.
-
- Secret tokens, should be specified in serviceConfig.EnvironmentFile
- instead of this world-readable attribute set.
-
- Configuration options should match those described as per your appservice's settings
- Check out the confg sample for this.
-
- '';
- };
-
- registrationData = mkOption {
- type = settingsFormat.type;
- default = asFormat.registrationData or {
- namespaces = {
- users = [
- {
- regex = "@${name}_.*:${homeserverDomain}";
- exclusive = true;
- }
- {
- regex = "@${name}bot:${homeserverDomain}";
- exclusive = true;
- }
- ];
- };
- };
- defaultText = ''
- Reserve usernames under the homeserver that start with
- this appservice's name followed by an _ or "bot"
- '';
- description = ''
- Data to set in the registration file for the appservice. The default
- set or the format should usually deal with this.
- '';
- };
-
- host = mkOption {
- type = types.str;
- default = "localhost";
- description = ''
- The host the appservice will listen on.
- Will need to specified in config, but most formats will do it for you using
- this option.
- '';
- };
-
- port = mkOption {
- type = types.port;
- description = ''
- The port the appservice will listen on.
- Will need to specified in config, but most formats will do it for you using
- this option.
- '';
- };
-
- startupScript = mkOption {
- type = types.str;
- default = asFormat.startupScript or "";
- description = ''
- Script that starts the appservice.
- The settings file will be available as $SETTINGS_FILE
- and the registration file as $REGISTRATION_FILE
- '';
- };
-
- serviceConfig = mkOption rec {
- type = types.attrs;
- apply = x: default // x;
- default = asFormat.serviceConfig or { };
- description = ''
- Overrides for settings in the service's serviceConfig
- '';
- };
-
- serviceDependencies = mkOption {
- type = types.listOf types.str;
- default = [ ];
- description = ''
- Services started before this appservice
- '';
- };
- };
- })
diff --git a/module/default.nix b/module/default.nix
deleted file mode 100644
index f57284d..0000000
--- a/module/default.nix
+++ /dev/null
@@ -1,180 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-let
- cfg = config.services.matrix-appservices;
- asOpts = import ./as-options.nix {
- inherit lib pkgs;
- systemConfig = config;
- };
- mkService = name: opts:
- with opts;
- let
- settingsFormat = pkgs.formats.json { };
- dataDir = "/var/lib/matrix-as-${name}";
- registrationFile = "${dataDir}/${name}-registration.yaml";
- # Replace all references to $DIR to the dat directory
- settingsData = settingsFormat.generate "config.json" settings;
- settingsFile = "${dataDir}/config.json";
- serviceDeps = [ "network-online.target" ] ++ serviceDependencies;
-
- registrationContent = {
- id = name;
- url = "http://${host}:${toString port}";
- as_token = "$AS_TOKEN";
- hs_token = "$HS_TOKEN";
- sender_localpart = "$SENDER_LOCALPART";
- rate_limited = false;
- } // registrationData;
- in
- {
- description = "A matrix appservice for ${name}.";
-
- wantedBy = [ "multi-user.target" ];
- wants = serviceDeps;
- after = serviceDeps;
- # Appservices don't need synapse up, but synapse exists if registration files are missing
- before = mkIf (cfg.homeserver != null) [ "${cfg.homeserver}.service" ];
-
- path = [ pkgs.yq ];
- environment = {
- DIR = dataDir;
- SETTINGS_FILE = settingsFile;
- REGISTRATION_FILE = registrationFile;
- };
-
- preStart = ''
- if [ ! -f ${registrationFile} ]; then
- AS_TOKEN=$(cat /proc/sys/kernel/random/uuid) \
- HS_TOKEN=$(cat /proc/sys/kernel/random/uuid) \
- SENDER_LOCALPART=$(cat /proc/sys/kernel/random/uuid) \
- ${pkgs.envsubst}/bin/envsubst \
- -i ${settingsFormat.generate "config.json" registrationContent} \
- -o ${registrationFile}
-
- chmod 640 ${registrationFile}
- fi
-
- AS_TOKEN=$(cat ${registrationFile} | yq .as_token | tr -d '"') \
- HS_TOKEN=$(cat ${registrationFile} | yq .hs_token | tr -d '"') \
- ${pkgs.envsubst}/bin/envsubst -i ${settingsData} -o ${settingsFile}
- chmod 640 ${settingsFile}
- '';
-
- script = startupScript;
-
- serviceConfig = {
- Type = "simple";
- Restart = "always";
-
- ProtectSystem = "strict";
- PrivateTmp = true;
- ProtectHome = true;
- ProtectKernelTunables = true;
- ProtectKernelModules = true;
- ProtectControlGroups = true;
-
- User = "matrix-as-${name}";
- Group = "matrix-as-${name}";
- WorkingDirectory = dataDir;
- StateDirectory = baseNameOf dataDir;
- StateDirectoryMode = "0750";
- UMask = 0027;
- } // opts.serviceConfig;
- };
-
-in
-{
- options = {
- services.matrix-appservices = {
- services = mkOption {
- type = types.attrsOf asOpts;
- default = { };
- example = literalExpression ''
- whatsapp = {
- format = "mautrix-go";
- package = pkgs.mautrix-whatsapp;
- };
- '';
- description = ''
- Appservices to setup.
- Each appservice will be started as a systemd service with the prefix matrix-as.
- And its data will be stored in /var/lib/matrix-as-name.
- '';
- };
-
- homeserver = mkOption {
- type = types.enum [ "matrix-synapse" "dendrite" null ];
- default = "matrix-synapse";
- description = ''
- The homeserver software the appservices connect to. This will ensure appservices
- start after the homeserver and it will be used by the addRegistrationFiles option.
- '';
- };
-
- homeserverURL = mkOption {
- type = types.str;
- default = "https://${cfg.homeserverDomain}";
- description = ''
- URL of the homeserver the apservices connect to
- '';
- };
-
- homeserverDomain = mkOption {
- type = types.str;
- default = if config.networking.domain != null then config.networking.domain else "";
- defaultText = "\${config.networking.domain}";
- description = ''
- Domain of the homeserver the appservices connect to
- '';
- };
-
- addRegistrationFiles = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether to add the application service registration files to the homeserver configuration.
- It is recommended to verify appservice files, located in /var/lib/matrix-as-*, before adding them
- '';
- };
- };
- };
-
- config = mkIf (cfg.services != { }) {
-
- assertions = mapAttrsToList
- (n: v: {
- assertion = v.format == "other" || v.package != null;
- message = "A package must be provided if a custom format is set";
- })
- cfg.services;
-
- users.users = mapAttrs'
- (n: v: nameValuePair "matrix-as-${n}" {
- group = "matrix-as-${n}";
- isSystemUser = true;
- })
- cfg.services;
- users.groups = mapAttrs' (n: v: nameValuePair "matrix-as-${n}" { }) cfg.services;
-
- # Create a service for each appservice
- systemd.services = (mapAttrs' (n: v: nameValuePair "matrix-as-${n}" (mkService n v)) cfg.services) // {
- # Add the matrix service to the groups of all appservices to give access to the registration file
- matrix-synapse.serviceConfig.SupplementaryGroups = mapAttrsToList (n: v: "matrix-as-${n}") cfg.services;
- dendrite.serviceConfig.SupplementaryGroups = mapAttrsToList (n: v: "matrix-as-${n}") cfg.services;
- };
-
- services =
- let
- registrationFiles = mapAttrsToList (n: _: "/var/lib/matrix-as-${n}/${n}-registration.yaml")
- (filterAttrs (_: v: v.registrationData != { }) cfg.services);
- in
- mkIf cfg.addRegistrationFiles {
- matrix-synapse.app_service_config_files = mkIf (cfg.homeserver == "matrix-synapse") registrationFiles;
- dendrite.settings.app_service_api.config_files = mkIf (cfg.homeserver == "dendrite") registrationFiles;
- };
- };
-
- meta.maintainers = with maintainers; [ pacman99 Flakebi ];
-
-}