nixos/maubot: init
This commit is contained in:
parent
e96b8fd970
commit
00070cf866
|
@ -14,7 +14,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
|
||||||
- Create the first release note entry in this section!
|
- [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable).
|
||||||
|
|
||||||
## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
|
## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
|
||||||
|
|
||||||
|
|
|
@ -621,6 +621,7 @@
|
||||||
./services/matrix/appservice-irc.nix
|
./services/matrix/appservice-irc.nix
|
||||||
./services/matrix/conduit.nix
|
./services/matrix/conduit.nix
|
||||||
./services/matrix/dendrite.nix
|
./services/matrix/dendrite.nix
|
||||||
|
./services/matrix/maubot.nix
|
||||||
./services/matrix/mautrix-facebook.nix
|
./services/matrix/mautrix-facebook.nix
|
||||||
./services/matrix/mautrix-telegram.nix
|
./services/matrix/mautrix-telegram.nix
|
||||||
./services/matrix/mautrix-whatsapp.nix
|
./services/matrix/mautrix-whatsapp.nix
|
||||||
|
|
103
nixos/modules/services/matrix/maubot.md
Normal file
103
nixos/modules/services/matrix/maubot.md
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# Maubot {#module-services-maubot}
|
||||||
|
|
||||||
|
[Maubot](https://github.com/maubot/maubot) is a plugin-based bot
|
||||||
|
framework for Matrix.
|
||||||
|
|
||||||
|
## Configuration {#module-services-maubot-configuration}
|
||||||
|
|
||||||
|
1. Set [](#opt-services.maubot.enable) to `true`. The service will use
|
||||||
|
SQLite by default.
|
||||||
|
2. If you want to use PostgreSQL instead of SQLite, do this:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
|
||||||
|
```
|
||||||
|
|
||||||
|
If the PostgreSQL connection requires a password, you will have to
|
||||||
|
add it later on step 8.
|
||||||
|
3. If you plan to expose your Maubot interface to the web, do something
|
||||||
|
like this:
|
||||||
|
```nix
|
||||||
|
services.nginx.virtualHosts."matrix.example.org".locations = {
|
||||||
|
"/_matrix/maubot/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.maubot.settings.server.public_url = "matrix.example.org";
|
||||||
|
# do the following only if you want to use something other than /_matrix/maubot...
|
||||||
|
services.maubot.settings.server.ui_base_path = "/another/base/path";
|
||||||
|
```
|
||||||
|
4. Optionally, set `services.maubot.pythonPackages` to a list of python3
|
||||||
|
packages to make available for Maubot plugins.
|
||||||
|
5. Optionally, set `services.maubot.plugins` to a list of Maubot
|
||||||
|
plugins (full list available at https://plugins.maubot.xyz/):
|
||||||
|
```nix
|
||||||
|
services.maubot.plugins = with config.services.maubot.package.plugins; [
|
||||||
|
reactbot
|
||||||
|
# This will only change the default config! After you create a
|
||||||
|
# plugin instance, the default config will be copied into that
|
||||||
|
# instance's config in Maubot's database, and further base config
|
||||||
|
# changes won't affect the running plugin.
|
||||||
|
(rss.override {
|
||||||
|
base_config = {
|
||||||
|
update_interval = 60;
|
||||||
|
max_backoff = 7200;
|
||||||
|
spam_sleep = 2;
|
||||||
|
command_prefix = "rss";
|
||||||
|
admins = [ "@chayleaf:pavluk.org" ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
# ...or...
|
||||||
|
services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
|
||||||
|
# ...or...
|
||||||
|
services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
|
||||||
|
# ...or...
|
||||||
|
services.maubot.plugins = with config.services.maubot.package.plugins; [
|
||||||
|
(weather.override {
|
||||||
|
# you can pass base_config as a string
|
||||||
|
base_config = ''
|
||||||
|
default_location: New York
|
||||||
|
default_units: M
|
||||||
|
default_language:
|
||||||
|
show_link: true
|
||||||
|
show_image: false
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
```
|
||||||
|
6. Start Maubot at least once before doing the following steps (it's
|
||||||
|
necessary to generate the initial config).
|
||||||
|
7. If your PostgreSQL connection requires a password, add
|
||||||
|
`database: postgresql://user:password@localhost/maubot`
|
||||||
|
to `/var/lib/maubot/config.yaml`. This overrides the Nix-provided
|
||||||
|
config. Even then, don't remove the `database` line from Nix config
|
||||||
|
so the module knows you use PostgreSQL!
|
||||||
|
8. To create a user account for logging into Maubot web UI and
|
||||||
|
configuring it, generate a password using the shell command
|
||||||
|
`mkpasswd -R 12 -m bcrypt`, and edit `/var/lib/maubot/config.yaml`
|
||||||
|
with the following:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
admins:
|
||||||
|
admin_username: $2b$12$g.oIStUeUCvI58ebYoVMtO/vb9QZJo81PsmVOomHiNCFbh0dJpZVa
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `admin_username` is your username, and `$2b...` is the bcrypted
|
||||||
|
password.
|
||||||
|
9. Optional: if you want to be able to register new users with the
|
||||||
|
Maubot CLI (`mbc`), and your homeserver is private, add your
|
||||||
|
homeserver's registration key to `/var/lib/maubot/config.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
homeservers:
|
||||||
|
matrix.example.org:
|
||||||
|
url: https://matrix.example.org
|
||||||
|
secret: your-very-secret-key
|
||||||
|
```
|
||||||
|
10. Restart Maubot after editing `/var/lib/maubot/config.yaml`,and
|
||||||
|
Maubot will be available at
|
||||||
|
`https://matrix.example.org/_matrix/maubot`. If you want to use the
|
||||||
|
`mbc` CLI, it's available using the `maubot` package (`nix-shell -p
|
||||||
|
maubot`).
|
459
nixos/modules/services/matrix/maubot.nix
Normal file
459
nixos/modules/services/matrix/maubot.nix
Normal file
|
@ -0,0 +1,459 @@
|
||||||
|
{ lib
|
||||||
|
, config
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.maubot;
|
||||||
|
|
||||||
|
wrapper1 =
|
||||||
|
if cfg.plugins == [ ]
|
||||||
|
then cfg.package
|
||||||
|
else cfg.package.withPlugins (_: cfg.plugins);
|
||||||
|
|
||||||
|
wrapper2 =
|
||||||
|
if cfg.pythonPackages == [ ]
|
||||||
|
then wrapper1
|
||||||
|
else wrapper1.withPythonPackages (_: cfg.pythonPackages);
|
||||||
|
|
||||||
|
settings = lib.recursiveUpdate cfg.settings {
|
||||||
|
plugin_directories.trash =
|
||||||
|
if cfg.settings.plugin_directories.trash == null
|
||||||
|
then "delete"
|
||||||
|
else cfg.settings.plugin_directories.trash;
|
||||||
|
server.unshared_secret = "generate";
|
||||||
|
};
|
||||||
|
|
||||||
|
finalPackage = wrapper2.withBaseConfig settings;
|
||||||
|
|
||||||
|
isPostgresql = db: builtins.isString db && lib.hasPrefix "postgresql://" db;
|
||||||
|
isLocalPostgresDB = db: isPostgresql db && builtins.any (x: lib.hasInfix x db) [
|
||||||
|
"@127.0.0.1/"
|
||||||
|
"@::1/"
|
||||||
|
"@[::1]/"
|
||||||
|
"@localhost/"
|
||||||
|
];
|
||||||
|
parsePostgresDB = db:
|
||||||
|
let
|
||||||
|
noSchema = lib.removePrefix "postgresql://" db;
|
||||||
|
in {
|
||||||
|
username = builtins.head (lib.splitString "@" noSchema);
|
||||||
|
database = lib.last (lib.splitString "/" noSchema);
|
||||||
|
};
|
||||||
|
|
||||||
|
postgresDBs = [
|
||||||
|
cfg.settings.database
|
||||||
|
cfg.settings.crypto_database
|
||||||
|
cfg.settings.plugin_databases.postgres
|
||||||
|
];
|
||||||
|
|
||||||
|
localPostgresDBs = builtins.filter isLocalPostgresDB postgresDBs;
|
||||||
|
|
||||||
|
parsedLocalPostgresDBs = map parsePostgresDB localPostgresDBs;
|
||||||
|
parsedPostgresDBs = map parsePostgresDB postgresDBs;
|
||||||
|
|
||||||
|
hasLocalPostgresDB = localPostgresDBs != [ ];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.maubot = with lib; {
|
||||||
|
enable = mkEnableOption (mdDoc "maubot");
|
||||||
|
|
||||||
|
package = lib.mkPackageOptionMD pkgs "maubot" { };
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExpression ''
|
||||||
|
with config.services.maubot.package.plugins; [
|
||||||
|
xyz.maubot.reactbot
|
||||||
|
xyz.maubot.rss
|
||||||
|
];
|
||||||
|
'';
|
||||||
|
description = mdDoc ''
|
||||||
|
List of additional maubot plugins to make available.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
pythonPackages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExpression ''
|
||||||
|
with pkgs.python3Packages; [
|
||||||
|
aiohttp
|
||||||
|
];
|
||||||
|
'';
|
||||||
|
description = mdDoc ''
|
||||||
|
List of additional Python packages to make available for maubot.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/var/lib/maubot";
|
||||||
|
description = mdDoc ''
|
||||||
|
The directory where maubot stores its stateful data.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfigFile = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "./config.yaml";
|
||||||
|
defaultText = literalExpression ''"''${config.services.maubot.dataDir}/config.yaml"'';
|
||||||
|
description = mdDoc ''
|
||||||
|
A file for storing secrets. You can pass homeserver registration keys here.
|
||||||
|
If it already exists, **it must contain `server.unshared_secret`** which is used for signing API keys.
|
||||||
|
If `configMutable` is not set to true, **maubot user must have write access to this file**.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configMutable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc ''
|
||||||
|
Whether maubot should write updated config into `extraConfigFile`. **This will make your Nix module settings have no effect besides the initial config, as extraConfigFile takes precedence over NixOS settings!**
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
default = { };
|
||||||
|
description = mdDoc ''
|
||||||
|
YAML settings for maubot. See the
|
||||||
|
[example configuration](https://github.com/maubot/maubot/blob/master/maubot/example-config.yaml)
|
||||||
|
for more info.
|
||||||
|
|
||||||
|
Secrets should be passed in by using `extraConfigFile`.
|
||||||
|
'';
|
||||||
|
type = with types; submodule {
|
||||||
|
options = {
|
||||||
|
database = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "sqlite:maubot.db";
|
||||||
|
example = "postgresql://username:password@hostname/dbname";
|
||||||
|
description = mdDoc ''
|
||||||
|
The full URI to the database. SQLite and Postgres are fully supported.
|
||||||
|
Other DBMSes supported by SQLAlchemy may or may not work.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
crypto_database = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "default";
|
||||||
|
example = "postgresql://username:password@hostname/dbname";
|
||||||
|
description = mdDoc ''
|
||||||
|
Separate database URL for the crypto database. By default, the regular database is also used for crypto.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
database_opts = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = mdDoc ''
|
||||||
|
Additional arguments for asyncpg.create_pool() or sqlite3.connect()
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin_directories = mkOption {
|
||||||
|
default = { };
|
||||||
|
description = mdDoc "Plugin directory paths";
|
||||||
|
type = submodule {
|
||||||
|
options = {
|
||||||
|
upload = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "./plugins";
|
||||||
|
defaultText = literalExpression ''"''${config.services.maubot.dataDir}/plugins"'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The directory where uploaded new plugins should be stored.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
load = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "./plugins" ];
|
||||||
|
defaultText = literalExpression ''[ "''${config.services.maubot.dataDir}/plugins" ]'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The directories from which plugins should be loaded. Duplicate plugin IDs will be moved to the trash.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
trash = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = "./trash";
|
||||||
|
defaultText = literalExpression ''"''${config.services.maubot.dataDir}/trash"'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The directory where old plugin versions and conflicting plugins should be moved. Set to null to delete files immediately.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin_databases = mkOption {
|
||||||
|
description = mdDoc "Plugin database settings";
|
||||||
|
default = { };
|
||||||
|
type = submodule {
|
||||||
|
options = {
|
||||||
|
sqlite = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "./plugins";
|
||||||
|
defaultText = literalExpression ''"''${config.services.maubot.dataDir}/plugins"'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The directory where SQLite plugin databases should be stored.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
postgres = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = if isPostgresql cfg.settings.database then "default" else null;
|
||||||
|
defaultText = literalExpression ''if isPostgresql config.services.maubot.settings.database then "default" else null'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The connection URL for plugin database. See [example config](https://github.com/maubot/maubot/blob/master/maubot/example-config.yaml) for exact format.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
postgres_max_conns_per_plugin = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = 3;
|
||||||
|
description = mdDoc ''
|
||||||
|
Maximum number of connections per plugin instance.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
postgres_opts = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = mdDoc ''
|
||||||
|
Overrides for the default database_opts when using a non-default postgres connection URL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
server = mkOption {
|
||||||
|
default = { };
|
||||||
|
description = mdDoc "Listener config";
|
||||||
|
type = submodule {
|
||||||
|
options = {
|
||||||
|
hostname = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
description = mdDoc ''
|
||||||
|
The IP to listen on
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 29316;
|
||||||
|
description = mdDoc ''
|
||||||
|
The port to listen on
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
public_url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "http://${cfg.settings.server.hostname}:${toString cfg.settings.server.port}";
|
||||||
|
defaultText = literalExpression ''"http://''${config.services.maubot.settings.server.hostname}:''${toString config.services.maubot.settings.server.port}"'';
|
||||||
|
description = mdDoc ''
|
||||||
|
Public base URL where the server is visible.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ui_base_path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/_matrix/maubot";
|
||||||
|
description = mdDoc ''
|
||||||
|
The base path for the UI.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
plugin_base_path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "${config.services.maubot.settings.server.ui_base_path}/plugin/";
|
||||||
|
defaultText = literalExpression ''
|
||||||
|
"''${config.services.maubot.settings.server.ui_base_path}/plugin/"
|
||||||
|
'';
|
||||||
|
description = mdDoc ''
|
||||||
|
The base path for plugin endpoints. The instance ID will be appended directly.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
override_resource_path = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
Override path from where to load UI resources.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
homeservers = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc ''
|
||||||
|
Client-server API URL
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = {
|
||||||
|
"matrix.org" = {
|
||||||
|
url = "https://matrix-client.matrix.org";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = mdDoc ''
|
||||||
|
Known homeservers. This is required for the `mbc auth` command and also allows more convenient access from the management UI.
|
||||||
|
If you want to specify registration secrets, pass this via extraConfigFile instead.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
admins = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { root = ""; };
|
||||||
|
description = mdDoc ''
|
||||||
|
List of administrator users. Plaintext passwords will be bcrypted on startup. Set empty password
|
||||||
|
to prevent normal login. Root is a special user that can't have a password and will always exist.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
api_features = mkOption {
|
||||||
|
type = types.attrsOf bool;
|
||||||
|
default = {
|
||||||
|
login = true;
|
||||||
|
plugin = true;
|
||||||
|
plugin_upload = true;
|
||||||
|
instance = true;
|
||||||
|
instance_database = true;
|
||||||
|
client = true;
|
||||||
|
client_proxy = true;
|
||||||
|
client_auth = true;
|
||||||
|
dev_open = true;
|
||||||
|
log = true;
|
||||||
|
};
|
||||||
|
description = mdDoc ''
|
||||||
|
API feature switches.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logging = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
description = mdDoc ''
|
||||||
|
Python logging configuration. See [section 16.7.2 of the Python
|
||||||
|
documentation](https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema)
|
||||||
|
for more info.
|
||||||
|
'';
|
||||||
|
default = {
|
||||||
|
version = 1;
|
||||||
|
formatters = {
|
||||||
|
colored = {
|
||||||
|
"()" = "maubot.lib.color_log.ColorFormatter";
|
||||||
|
format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
|
||||||
|
};
|
||||||
|
normal = {
|
||||||
|
format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
handlers = {
|
||||||
|
file = {
|
||||||
|
class = "logging.handlers.RotatingFileHandler";
|
||||||
|
formatter = "normal";
|
||||||
|
filename = "./maubot.log";
|
||||||
|
maxBytes = 10485760;
|
||||||
|
backupCount = 10;
|
||||||
|
};
|
||||||
|
console = {
|
||||||
|
class = "logging.StreamHandler";
|
||||||
|
formatter = "colored";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
loggers = {
|
||||||
|
maubot = {
|
||||||
|
level = "DEBUG";
|
||||||
|
};
|
||||||
|
mau = {
|
||||||
|
level = "DEBUG";
|
||||||
|
};
|
||||||
|
aiohttp = {
|
||||||
|
level = "INFO";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
level = "DEBUG";
|
||||||
|
handlers = [ "file" "console" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
warnings = lib.optional (builtins.any (x: x.username != x.database) parsedLocalPostgresDBs) ''
|
||||||
|
The Maubot database username doesn't match the database name! This means the user won't be automatically
|
||||||
|
granted ownership of the database. Consider changing either the username or the database name.
|
||||||
|
'';
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = builtins.all (x: !lib.hasInfix ":" x.username) parsedPostgresDBs;
|
||||||
|
message = ''
|
||||||
|
Putting database passwords in your Nix config makes them world-readable. To securely put passwords
|
||||||
|
in your Maubot config, change /var/lib/maubot/config.yaml after running Maubot at least once as
|
||||||
|
described in the NixOS manual.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = hasLocalPostgresDB -> config.services.postgresql.enable;
|
||||||
|
message = ''
|
||||||
|
Cannot deploy maubot with a configuration for a local postgresql database and a missing postgresql service.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.postgresql = lib.mkIf hasLocalPostgresDB {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = map (x: x.database) parsedLocalPostgresDBs;
|
||||||
|
ensureUsers = lib.flip map parsedLocalPostgresDBs (x: {
|
||||||
|
name = x.username;
|
||||||
|
ensureDBOwnership = lib.mkIf (x.username == x.database) true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.maubot = {
|
||||||
|
group = "maubot";
|
||||||
|
home = cfg.dataDir;
|
||||||
|
# otherwise StateDirectory is enough
|
||||||
|
createHome = lib.mkIf (cfg.dataDir != "/var/lib/maubot") true;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.maubot = { };
|
||||||
|
|
||||||
|
systemd.services.maubot = rec {
|
||||||
|
description = "maubot - a plugin-based Matrix bot system written in Python";
|
||||||
|
after = [ "network.target" ] ++ wants ++ lib.optional hasLocalPostgresDB "postgresql.service";
|
||||||
|
# all plugins get automatically disabled if maubot starts before synapse
|
||||||
|
wants = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
if [ ! -f "${cfg.extraConfigFile}" ]; then
|
||||||
|
echo "server:" > "${cfg.extraConfigFile}"
|
||||||
|
echo " unshared_secret: $(head -c40 /dev/random | base32 | ${pkgs.gawk}/bin/awk '{print tolower($0)}')" > "${cfg.extraConfigFile}"
|
||||||
|
chmod 640 "${cfg.extraConfigFile}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${finalPackage}/bin/maubot --config ${cfg.extraConfigFile}" + lib.optionalString (!cfg.configMutable) " --no-update";
|
||||||
|
User = "maubot";
|
||||||
|
Group = "maubot";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "10s";
|
||||||
|
StateDirectory = lib.mkIf (cfg.dataDir == "/var/lib/maubot") "maubot";
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ chayleaf ];
|
||||||
|
meta.doc = ./maubot.md;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user