mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-23 12:34:15 +00:00
Merge master into haskell-updates
This commit is contained in:
commit
179b0a961b
@ -361,6 +361,22 @@ modifications.
|
||||
|
||||
Do pay attention to passing in the right Python version!
|
||||
|
||||
#### `mkPythonMetaPackage` function {#mkpythonmetapackage-function}
|
||||
|
||||
This will create a meta package containing [metadata files](https://packaging.python.org/en/latest/specifications/recording-installed-packages/) to satisfy a dependency on a package, without it actually having been installed into the environment.
|
||||
In nixpkgs this is used to package Python packages with split binary/source distributions such as [psycopg2](https://pypi.org/project/psycopg2/)/[psycopg2-binary](https://pypi.org/project/psycopg2-binary/).
|
||||
|
||||
```nix
|
||||
mkPythonMetaPackage {
|
||||
pname = "psycopg2-binary";
|
||||
inherit (psycopg2) optional-dependencies version;
|
||||
dependencies = [ psycopg2 ];
|
||||
meta = {
|
||||
inherit (psycopg2.meta) description homepage;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### `python.buildEnv` function {#python.buildenv-function}
|
||||
|
||||
Python environments can be created using the low-level `pkgs.buildEnv` function.
|
||||
|
@ -1366,6 +1366,58 @@ let
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
`importApply file arg :: Path -> a -> Module`, where `import file :: a -> Module`
|
||||
|
||||
`importApply` imports a Nix expression file much like the module system would,
|
||||
after passing an extra positional argument to the function in the file.
|
||||
|
||||
This function should be used when declaring a module in a file that refers to
|
||||
values from a different scope, such as that in a flake.
|
||||
|
||||
It solves the problems of alternative solutions:
|
||||
|
||||
- While `importApply file arg` is _mostly_ equivalent to
|
||||
`import file arg`, the latter returns a module without a location,
|
||||
as `import` only returns the contained expression. This leads to worse
|
||||
error messages.
|
||||
|
||||
- Using `specialArgs` to provide arguments to all modules. This effectively
|
||||
creates an incomplete module, and requires the user of the module to
|
||||
manually pass the `specialArgs` to the configuration, which is error-prone,
|
||||
verbose, and unnecessary.
|
||||
|
||||
The nix file must contain a function that returns a module.
|
||||
A module may itself be a function, so the file is often a function with two
|
||||
positional arguments instead of one. See the example below.
|
||||
|
||||
This function does not add support for deduplication and `disabledModules`,
|
||||
although that could be achieved by wrapping the returned module and setting
|
||||
the `_key` module attribute.
|
||||
The reason for this omission is that the file path is not guaranteed to be
|
||||
a unique identifier for the module, as two instances of the module may
|
||||
reference different `arg`s in their closures.
|
||||
|
||||
Example
|
||||
|
||||
# lib.nix
|
||||
imports = [
|
||||
(lib.modules.importApply ./module.nix { bar = bar; })
|
||||
];
|
||||
|
||||
# module.nix
|
||||
{ bar }:
|
||||
{ lib, config, ... }:
|
||||
{
|
||||
options = ...;
|
||||
config = ... bar ...;
|
||||
}
|
||||
|
||||
*/
|
||||
importApply =
|
||||
modulePath: staticArg:
|
||||
lib.setDefaultModuleLocation modulePath (import modulePath staticArg);
|
||||
|
||||
/* Use this function to import a JSON file as NixOS configuration.
|
||||
|
||||
modules.importJSON :: path -> attrs
|
||||
@ -1415,6 +1467,7 @@ private //
|
||||
filterOverrides'
|
||||
fixMergeModules
|
||||
fixupOptionType # should be private?
|
||||
importApply
|
||||
importJSON
|
||||
importTOML
|
||||
mergeDefinitions
|
||||
|
@ -247,6 +247,14 @@ checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-if-foo-e
|
||||
checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-if-enable.nix
|
||||
checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable-if.nix
|
||||
|
||||
# Check importApply
|
||||
checkConfigOutput '"abc"' config.value ./importApply.nix
|
||||
# importApply does not set a key.
|
||||
# Disabling the function file is not sufficient, because importApply can't reasonably assume that the key is unique.
|
||||
# e.g. user may call it multiple times with different arguments and expect each of the module to apply.
|
||||
# While this is excusable for the disabledModules aspect, it is not for the deduplication of modules.
|
||||
checkConfigOutput '"abc"' config.value ./importApply-disabling.nix
|
||||
|
||||
# Check disabledModules with config definitions and option declarations.
|
||||
set -- config.enable ./define-enable.nix ./declare-enable.nix
|
||||
checkConfigOutput '^true$' "$@"
|
||||
|
4
lib/tests/modules/importApply-disabling.nix
Normal file
4
lib/tests/modules/importApply-disabling.nix
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
imports = [ ./importApply.nix ];
|
||||
disabledModules = [ ./importApply-function.nix ];
|
||||
}
|
5
lib/tests/modules/importApply-function.nix
Normal file
5
lib/tests/modules/importApply-function.nix
Normal file
@ -0,0 +1,5 @@
|
||||
{ foo }:
|
||||
{ lib, config, ... }:
|
||||
{
|
||||
value = foo;
|
||||
}
|
5
lib/tests/modules/importApply.nix
Normal file
5
lib/tests/modules/importApply.nix
Normal file
@ -0,0 +1,5 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.value = lib.mkOption { default = 1; };
|
||||
imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ];
|
||||
}
|
@ -3812,6 +3812,12 @@
|
||||
githubId = 199180;
|
||||
name = "Claes Wallin";
|
||||
};
|
||||
claes = {
|
||||
email = "claes.holmerson@gmail.com";
|
||||
github = "claes";
|
||||
githubId = 43564;
|
||||
name = "Claes Holmerson";
|
||||
};
|
||||
clebs = {
|
||||
email = "borja.clemente@gmail.com";
|
||||
github = "clebs";
|
||||
@ -9258,6 +9264,12 @@
|
||||
github = "jankaifer";
|
||||
githubId = 12820484;
|
||||
};
|
||||
janlikar = {
|
||||
name = "Jan Likar";
|
||||
email = "jan.likar@protonmail.com";
|
||||
github = "janlikar";
|
||||
githubId = 4228250;
|
||||
};
|
||||
jansol = {
|
||||
email = "jan.solanti@paivola.fi";
|
||||
github = "jansol";
|
||||
@ -18771,6 +18783,12 @@
|
||||
githubId = 307899;
|
||||
name = "Gurkan Gur";
|
||||
};
|
||||
sequencer = {
|
||||
email = "liu@jiuyang.me";
|
||||
github = "sequencer";
|
||||
githubId = 5791019;
|
||||
name = "Jiuyang Liu";
|
||||
};
|
||||
serge = {
|
||||
email = "sb@canva.com";
|
||||
github = "serge-belov";
|
||||
|
@ -315,6 +315,7 @@ with lib.maintainers;
|
||||
leona
|
||||
osnyx
|
||||
ma27
|
||||
laalsaas
|
||||
];
|
||||
scope = "Team for Flying Circus employees who collectively maintain packages.";
|
||||
shortName = "Flying Circus employees";
|
||||
|
@ -100,6 +100,9 @@ modified using `usermod`. Unix groups can be managed using `groupadd`,
|
||||
|
||||
::: {.note}
|
||||
This is experimental.
|
||||
|
||||
Please consider using [Userborn](#sec-userborn) over systemd-sysusers as it's
|
||||
more feature complete.
|
||||
:::
|
||||
|
||||
Instead of using a custom perl script to create users and groups, you can use
|
||||
@ -112,3 +115,43 @@ systemd-sysusers:
|
||||
```
|
||||
|
||||
The primary benefit of this is to remove a dependency on perl.
|
||||
|
||||
## Manage users and groups with `userborn` {#sec-userborn}
|
||||
|
||||
::: {.note}
|
||||
This is experimental.
|
||||
:::
|
||||
|
||||
Like systemd-sysusers, Userborn adoesn't depend on Perl but offers some more
|
||||
advantages over systemd-sysusers:
|
||||
|
||||
1. It can create "normal" users (with a GID >= 1000).
|
||||
2. It can update some information about users. Most notably it can update their
|
||||
passwords.
|
||||
3. It will warn when users use an insecure or unsupported password hashing
|
||||
scheme.
|
||||
|
||||
Userborn is the recommended way to manage users if you don't want to rely on
|
||||
the Perl script. It aims to eventually replace the Perl script by default.
|
||||
|
||||
You can enable Userborn via:
|
||||
|
||||
```nix
|
||||
services.userborn.enable = true;
|
||||
```
|
||||
|
||||
You can configure Userborn to store the password files
|
||||
(`/etc/{group,passwd,shadow}`) outside of `/etc` and symlink them from this
|
||||
location to `/etc`:
|
||||
|
||||
```nix
|
||||
services.userborn.passwordFilesLocation = "/persistent/etc";
|
||||
```
|
||||
|
||||
This is useful when you store `/etc` on a `tmpfs` or if `/etc` is immutable
|
||||
(e.g. when using `system.etc.overlay.mutable = false;`). In the latter case the
|
||||
original files are by default stored in `/var/lib/nixos`.
|
||||
|
||||
Userborn implements immutable users by re-mounting the password files
|
||||
read-only. This means that unlike when using the Perl script, trying to add a
|
||||
new user (e.g. via `useradd`) will fail right away.
|
||||
|
@ -41,6 +41,13 @@
|
||||
|
||||
- [Quickwit](https://quickwit.io), sub-second search & analytics engine on cloud storage. Available as [services.quickwit](options.html#opt-services.quickwit).
|
||||
|
||||
- [Userborn](https://github.com/nikstur/userborn), a service for declarative
|
||||
user management. This can be used instead of the `update-users-groups.pl`
|
||||
Perl script and instead of systemd-sysusers. To achieve a system without
|
||||
Perl, this is the now recommended tool over systemd-sysusers because it can
|
||||
alos create normal users and change passwords. Available as
|
||||
[services.userborn](#opt-services.userborn.enable)
|
||||
|
||||
- [Flood](https://flood.js.org/), a beautiful WebUI for various torrent clients. Available as [services.flood](options.html#opt-services.flood).
|
||||
|
||||
- [Firefly-iii Data Importer](https://github.com/firefly-iii/data-importer), a data importer for Firefly-III. Available as [services.firefly-iii-data-importer](options.html#opt-services.firefly-iii-data-importer)
|
||||
|
@ -1,26 +1,23 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
i18n = {
|
||||
glibcLocales = mkOption {
|
||||
type = types.path;
|
||||
glibcLocales = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = pkgs.glibcLocales.override {
|
||||
allLocales = any (x: x == "all") config.i18n.supportedLocales;
|
||||
allLocales = lib.any (x: x == "all") config.i18n.supportedLocales;
|
||||
locales = config.i18n.supportedLocales;
|
||||
};
|
||||
defaultText = literalExpression ''
|
||||
defaultText = lib.literalExpression ''
|
||||
pkgs.glibcLocales.override {
|
||||
allLocales = any (x: x == "all") config.i18n.supportedLocales;
|
||||
locales = config.i18n.supportedLocales;
|
||||
}
|
||||
'';
|
||||
example = literalExpression "pkgs.glibcLocales";
|
||||
example = lib.literalExpression "pkgs.glibcLocales";
|
||||
description = ''
|
||||
Customized pkg.glibcLocales package.
|
||||
|
||||
@ -29,8 +26,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
defaultLocale = mkOption {
|
||||
type = types.str;
|
||||
defaultLocale = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "en_US.UTF-8";
|
||||
example = "nl_NL.UTF-8";
|
||||
description = ''
|
||||
@ -40,8 +37,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
extraLocaleSettings = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
extraLocaleSettings = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = {};
|
||||
example = { LC_MESSAGES = "en_US.UTF-8"; LC_TIME = "de_DE.UTF-8"; };
|
||||
description = ''
|
||||
@ -51,24 +48,24 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
supportedLocales = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = unique
|
||||
(builtins.map (l: (replaceStrings [ "utf8" "utf-8" "UTF8" ] [ "UTF-8" "UTF-8" "UTF-8" ] l) + "/UTF-8") (
|
||||
supportedLocales = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = lib.unique
|
||||
(builtins.map (l: (lib.replaceStrings [ "utf8" "utf-8" "UTF8" ] [ "UTF-8" "UTF-8" "UTF-8" ] l) + "/UTF-8") (
|
||||
[
|
||||
"C.UTF-8"
|
||||
"en_US.UTF-8"
|
||||
config.i18n.defaultLocale
|
||||
] ++ (attrValues (filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
|
||||
] ++ (lib.attrValues (lib.filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
|
||||
));
|
||||
defaultText = literalExpression ''
|
||||
unique
|
||||
(builtins.map (l: (replaceStrings [ "utf8" "utf-8" "UTF8" ] [ "UTF-8" "UTF-8" "UTF-8" ] l) + "/UTF-8") (
|
||||
defaultText = lib.literalExpression ''
|
||||
lib.unique
|
||||
(builtins.map (l: (lib.replaceStrings [ "utf8" "utf-8" "UTF8" ] [ "UTF-8" "UTF-8" "UTF-8" ] l) + "/UTF-8") (
|
||||
[
|
||||
"C.UTF-8"
|
||||
"en_US.UTF-8"
|
||||
config.i18n.defaultLocale
|
||||
] ++ (attrValues (filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
|
||||
] ++ (lib.attrValues (lib.filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
|
||||
))
|
||||
'';
|
||||
example = ["en_US.UTF-8/UTF-8" "nl_NL.UTF-8/UTF-8" "nl_NL/ISO-8859-1"];
|
||||
@ -91,14 +88,14 @@ with lib;
|
||||
|
||||
environment.systemPackages =
|
||||
# We increase the priority a little, so that plain glibc in systemPackages can't win.
|
||||
optional (config.i18n.supportedLocales != []) (lib.setPrio (-1) config.i18n.glibcLocales);
|
||||
lib.optional (config.i18n.supportedLocales != []) (lib.setPrio (-1) config.i18n.glibcLocales);
|
||||
|
||||
environment.sessionVariables =
|
||||
{ LANG = config.i18n.defaultLocale;
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
} // config.i18n.extraLocaleSettings;
|
||||
|
||||
systemd.globalEnvironment = mkIf (config.i18n.supportedLocales != []) {
|
||||
systemd.globalEnvironment = lib.mkIf (config.i18n.supportedLocales != []) {
|
||||
LOCALE_ARCHIVE = "${config.i18n.glibcLocales}/lib/locale/locale-archive";
|
||||
};
|
||||
|
||||
@ -106,7 +103,7 @@ with lib;
|
||||
environment.etc."locale.conf".source = pkgs.writeText "locale.conf"
|
||||
''
|
||||
LANG=${config.i18n.defaultLocale}
|
||||
${concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") config.i18n.extraLocaleSettings)}
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "${n}=${v}") config.i18n.extraLocaleSettings)}
|
||||
'';
|
||||
|
||||
};
|
||||
|
@ -1,10 +1,6 @@
|
||||
# This module defines a global environment configuration and
|
||||
# a common configuration for all shells.
|
||||
|
||||
{ config, lib, utils, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.environment;
|
||||
@ -12,27 +8,27 @@ let
|
||||
exportedEnvVars =
|
||||
let
|
||||
absoluteVariables =
|
||||
mapAttrs (n: toList) cfg.variables;
|
||||
lib.mapAttrs (n: lib.toList) cfg.variables;
|
||||
|
||||
suffixedVariables =
|
||||
flip mapAttrs cfg.profileRelativeEnvVars (envVar: listSuffixes:
|
||||
concatMap (profile: map (suffix: "${profile}${suffix}") listSuffixes) cfg.profiles
|
||||
lib.flip lib.mapAttrs cfg.profileRelativeEnvVars (envVar: listSuffixes:
|
||||
lib.concatMap (profile: map (suffix: "${profile}${suffix}") listSuffixes) cfg.profiles
|
||||
);
|
||||
|
||||
allVariables =
|
||||
zipAttrsWith (n: concatLists) [ absoluteVariables suffixedVariables ];
|
||||
lib.zipAttrsWith (n: lib.concatLists) [ absoluteVariables suffixedVariables ];
|
||||
|
||||
exportVariables =
|
||||
mapAttrsToList (n: v: ''export ${n}="${concatStringsSep ":" v}"'') allVariables;
|
||||
lib.mapAttrsToList (n: v: ''export ${n}="${lib.concatStringsSep ":" v}"'') allVariables;
|
||||
in
|
||||
concatStringsSep "\n" exportVariables;
|
||||
lib.concatStringsSep "\n" exportVariables;
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
environment.variables = mkOption {
|
||||
environment.variables = lib.mkOption {
|
||||
default = {};
|
||||
example = { EDITOR = "nvim"; VISUAL = "nvim"; };
|
||||
description = ''
|
||||
@ -42,22 +38,22 @@ in
|
||||
strings. The latter is concatenated, interspersed with colon
|
||||
characters.
|
||||
'';
|
||||
type = with types; attrsOf (oneOf [ (listOf (oneOf [ int str path ])) int str path ]);
|
||||
type = with lib.types; attrsOf (oneOf [ (listOf (oneOf [ int str path ])) int str path ]);
|
||||
apply = let
|
||||
toStr = v: if isPath v then "${v}" else toString v;
|
||||
in mapAttrs (n: v: if isList v then concatMapStringsSep ":" toStr v else toStr v);
|
||||
toStr = v: if lib.isPath v then "${v}" else toString v;
|
||||
in lib.mapAttrs (n: v: if lib.isList v then lib.concatMapStringsSep ":" toStr v else toStr v);
|
||||
};
|
||||
|
||||
environment.profiles = mkOption {
|
||||
environment.profiles = lib.mkOption {
|
||||
default = [];
|
||||
description = ''
|
||||
A list of profiles used to setup the global environment.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
};
|
||||
|
||||
environment.profileRelativeEnvVars = mkOption {
|
||||
type = types.attrsOf (types.listOf types.str);
|
||||
environment.profileRelativeEnvVars = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||
example = { PATH = [ "/bin" ]; MANPATH = [ "/man" "/share/man" ]; };
|
||||
description = ''
|
||||
Attribute set of environment variable. Each attribute maps to a list
|
||||
@ -68,7 +64,7 @@ in
|
||||
};
|
||||
|
||||
# !!! isn't there a better way?
|
||||
environment.extraInit = mkOption {
|
||||
environment.extraInit = lib.mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during global environment initialisation
|
||||
@ -76,40 +72,40 @@ in
|
||||
This code is assumed to be shell-independent, which means you should
|
||||
stick to pure sh without sh word split.
|
||||
'';
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
};
|
||||
|
||||
environment.shellInit = mkOption {
|
||||
environment.shellInit = lib.mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during shell initialisation.
|
||||
This code is assumed to be shell-independent, which means you should
|
||||
stick to pure sh without sh word split.
|
||||
'';
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
};
|
||||
|
||||
environment.loginShellInit = mkOption {
|
||||
environment.loginShellInit = lib.mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during login shell initialisation.
|
||||
This code is assumed to be shell-independent, which means you should
|
||||
stick to pure sh without sh word split.
|
||||
'';
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
};
|
||||
|
||||
environment.interactiveShellInit = mkOption {
|
||||
environment.interactiveShellInit = lib.mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during interactive shell initialisation.
|
||||
This code is assumed to be shell-independent, which means you should
|
||||
stick to pure sh without sh word split.
|
||||
'';
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
};
|
||||
|
||||
environment.shellAliases = mkOption {
|
||||
environment.shellAliases = lib.mkOption {
|
||||
example = { l = null; ll = "ls -l"; };
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names in
|
||||
@ -117,30 +113,30 @@ in
|
||||
aliases are added to all users' shells.
|
||||
Aliases mapped to `null` are ignored.
|
||||
'';
|
||||
type = with types; attrsOf (nullOr (either str path));
|
||||
type = with lib.types; attrsOf (nullOr (either str path));
|
||||
};
|
||||
|
||||
environment.homeBinInPath = mkOption {
|
||||
environment.homeBinInPath = lib.mkOption {
|
||||
description = ''
|
||||
Include ~/bin/ in $PATH.
|
||||
'';
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
environment.localBinInPath = mkOption {
|
||||
environment.localBinInPath = lib.mkOption {
|
||||
description = ''
|
||||
Add ~/.local/bin/ to $PATH
|
||||
'';
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
environment.binsh = mkOption {
|
||||
environment.binsh = lib.mkOption {
|
||||
default = "${config.system.build.binsh}/bin/sh";
|
||||
defaultText = literalExpression ''"''${config.system.build.binsh}/bin/sh"'';
|
||||
example = literalExpression ''"''${pkgs.dash}/bin/dash"'';
|
||||
type = types.path;
|
||||
defaultText = lib.literalExpression ''"''${config.system.build.binsh}/bin/sh"'';
|
||||
example = lib.literalExpression ''"''${pkgs.dash}/bin/dash"'';
|
||||
type = lib.types.path;
|
||||
visible = false;
|
||||
description = ''
|
||||
The shell executable that is linked system-wide to
|
||||
@ -150,15 +146,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
environment.shells = mkOption {
|
||||
environment.shells = lib.mkOption {
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.bashInteractive pkgs.zsh ]";
|
||||
example = lib.literalExpression "[ pkgs.bashInteractive pkgs.zsh ]";
|
||||
description = ''
|
||||
A list of permissible login shells for user accounts.
|
||||
No need to mention `/bin/sh`
|
||||
here, it is placed into this list implicitly.
|
||||
'';
|
||||
type = types.listOf (types.either types.shellPackage types.path);
|
||||
type = lib.types.listOf (lib.types.either lib.types.shellPackage lib.types.path);
|
||||
};
|
||||
|
||||
};
|
||||
@ -175,7 +171,7 @@ in
|
||||
|
||||
environment.profileRelativeEnvVars = config.environment.profileRelativeSessionVariables;
|
||||
|
||||
environment.shellAliases = mapAttrs (name: mkDefault) {
|
||||
environment.shellAliases = lib.mapAttrs (name: lib.mkDefault) {
|
||||
ls = "ls --color=tty";
|
||||
ll = "ls -l";
|
||||
l = "ls -alh";
|
||||
@ -183,7 +179,7 @@ in
|
||||
|
||||
environment.etc.shells.text =
|
||||
''
|
||||
${concatStringsSep "\n" (map utils.toShellPath cfg.shells)}
|
||||
${lib.concatStringsSep "\n" (map utils.toShellPath cfg.shells)}
|
||||
/bin/sh
|
||||
'';
|
||||
|
||||
@ -202,17 +198,17 @@ in
|
||||
|
||||
${cfg.extraInit}
|
||||
|
||||
${optionalString cfg.homeBinInPath ''
|
||||
${lib.optionalString cfg.homeBinInPath ''
|
||||
# ~/bin if it exists overrides other bin directories.
|
||||
export PATH="$HOME/bin:$PATH"
|
||||
''}
|
||||
|
||||
${optionalString cfg.localBinInPath ''
|
||||
${lib.optionalString cfg.localBinInPath ''
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
''}
|
||||
'';
|
||||
|
||||
system.activationScripts.binsh = stringAfter [ "stdio" ]
|
||||
system.activationScripts.binsh = lib.stringAfter [ "stdio" ]
|
||||
''
|
||||
# Create the required /bin/sh symlink; otherwise lots of things
|
||||
# (notably the system() function) won't work.
|
||||
|
@ -1,17 +1,14 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
sysctlOption = mkOptionType {
|
||||
sysctlOption = lib.mkOptionType {
|
||||
name = "sysctl option value";
|
||||
check = val:
|
||||
let
|
||||
checkType = x: isBool x || isString x || isInt x || x == null;
|
||||
checkType = x: lib.isBool x || lib.isString x || lib.isInt x || x == null;
|
||||
in
|
||||
checkType val || (val._type or "" == "override" && checkType val.content);
|
||||
merge = loc: defs: mergeOneOption loc (filterOverrides defs);
|
||||
merge = loc: defs: lib.mergeOneOption loc (lib.filterOverrides defs);
|
||||
};
|
||||
|
||||
in
|
||||
@ -20,33 +17,33 @@ in
|
||||
|
||||
options = {
|
||||
|
||||
boot.kernel.sysctl = mkOption {
|
||||
boot.kernel.sysctl = lib.mkOption {
|
||||
type = let
|
||||
highestValueType = types.ints.unsigned // {
|
||||
highestValueType = lib.types.ints.unsigned // {
|
||||
merge = loc: defs:
|
||||
foldl
|
||||
lib.foldl
|
||||
(a: b: if b.value == null then null else lib.max a b.value)
|
||||
0
|
||||
(filterOverrides defs);
|
||||
(lib.filterOverrides defs);
|
||||
};
|
||||
in types.submodule {
|
||||
freeformType = types.attrsOf sysctlOption;
|
||||
in lib.types.submodule {
|
||||
freeformType = lib.types.attrsOf sysctlOption;
|
||||
options = {
|
||||
"net.core.rmem_max" = mkOption {
|
||||
type = types.nullOr highestValueType;
|
||||
"net.core.rmem_max" = lib.mkOption {
|
||||
type = lib.types.nullOr highestValueType;
|
||||
default = null;
|
||||
description = "The maximum receive socket buffer size in bytes. In case of conflicting values, the highest will be used.";
|
||||
};
|
||||
|
||||
"net.core.wmem_max" = mkOption {
|
||||
type = types.nullOr highestValueType;
|
||||
"net.core.wmem_max" = lib.mkOption {
|
||||
type = lib.types.nullOr highestValueType;
|
||||
default = null;
|
||||
description = "The maximum send socket buffer size in bytes. In case of conflicting values, the highest will be used.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{ "net.ipv4.tcp_syncookies" = false; "vm.swappiness" = 60; }
|
||||
'';
|
||||
description = ''
|
||||
@ -66,8 +63,8 @@ in
|
||||
config = {
|
||||
|
||||
environment.etc."sysctl.d/60-nixos.conf".text =
|
||||
concatStrings (mapAttrsToList (n: v:
|
||||
optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n"
|
||||
lib.concatStrings (lib.mapAttrsToList (n: v:
|
||||
lib.optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n"
|
||||
) config.boot.kernel.sysctl);
|
||||
|
||||
systemd.services.systemd-sysctl =
|
||||
@ -77,10 +74,10 @@ in
|
||||
|
||||
# Hide kernel pointers (e.g. in /proc/modules) for unprivileged
|
||||
# users as these make it easier to exploit kernel vulnerabilities.
|
||||
boot.kernel.sysctl."kernel.kptr_restrict" = mkDefault 1;
|
||||
boot.kernel.sysctl."kernel.kptr_restrict" = lib.mkDefault 1;
|
||||
|
||||
# Improve compatibility with applications that allocate
|
||||
# a lot of memory, like modern games
|
||||
boot.kernel.sysctl."vm.max_map_count" = mkDefault 1048576;
|
||||
boot.kernel.sysctl."vm.max_map_count" = lib.mkDefault 1048576;
|
||||
};
|
||||
}
|
||||
|
@ -1,16 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
hardware.cpu.amd.updateMicrocode = mkOption {
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Update the CPU microcode for AMD processors.
|
||||
'';
|
||||
@ -18,12 +13,10 @@ with lib;
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.cpu.amd.updateMicrocode {
|
||||
config = lib.mkIf config.hardware.cpu.amd.updateMicrocode {
|
||||
# Microcode updates must be the first item prepended in the initrd
|
||||
boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
|
||||
boot.initrd.prepend = lib.mkOrder 1 [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,24 +1,23 @@
|
||||
{ config, options, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfgSev = config.hardware.cpu.amd.sev;
|
||||
cfgSevGuest = config.hardware.cpu.amd.sevGuest;
|
||||
|
||||
optionsFor = device: group: {
|
||||
enable = mkEnableOption "access to the AMD ${device} device";
|
||||
user = mkOption {
|
||||
enable = lib.mkEnableOption "access to the AMD ${device} device";
|
||||
user = lib.mkOption {
|
||||
description = "Owner to assign to the ${device} device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
};
|
||||
group = mkOption {
|
||||
group = lib.mkOption {
|
||||
description = "Group to assign to the ${device} device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = group;
|
||||
};
|
||||
mode = mkOption {
|
||||
mode = lib.mkOption {
|
||||
description = "Mode to set for the ${device} device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = "0660";
|
||||
};
|
||||
};
|
||||
@ -28,16 +27,16 @@ with lib; {
|
||||
|
||||
options.hardware.cpu.amd.sevGuest = optionsFor "SEV guest" "sev-guest";
|
||||
|
||||
config = mkMerge [
|
||||
config = lib.mkMerge [
|
||||
# /dev/sev
|
||||
(mkIf cfgSev.enable {
|
||||
(lib.mkIf cfgSev.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = hasAttr cfgSev.user config.users.users;
|
||||
assertion = lib.hasAttr cfgSev.user config.users.users;
|
||||
message = "Given user does not exist";
|
||||
}
|
||||
{
|
||||
assertion = (cfgSev.group == options.hardware.cpu.amd.sev.group.default) || (hasAttr cfgSev.group config.users.groups);
|
||||
assertion = (cfgSev.group == options.hardware.cpu.amd.sev.group.default) || (lib.hasAttr cfgSev.group config.users.groups);
|
||||
message = "Given group does not exist";
|
||||
}
|
||||
];
|
||||
@ -46,7 +45,7 @@ with lib; {
|
||||
options kvm_amd sev=1
|
||||
'';
|
||||
|
||||
users.groups = optionalAttrs (cfgSev.group == options.hardware.cpu.amd.sev.group.default) {
|
||||
users.groups = lib.optionalAttrs (cfgSev.group == options.hardware.cpu.amd.sev.group.default) {
|
||||
"${cfgSev.group}" = { };
|
||||
};
|
||||
|
||||
@ -56,19 +55,19 @@ with lib; {
|
||||
})
|
||||
|
||||
# /dev/sev-guest
|
||||
(mkIf cfgSevGuest.enable {
|
||||
(lib.mkIf cfgSevGuest.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = hasAttr cfgSevGuest.user config.users.users;
|
||||
assertion = lib.hasAttr cfgSevGuest.user config.users.users;
|
||||
message = "Given user does not exist";
|
||||
}
|
||||
{
|
||||
assertion = (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) || (hasAttr cfgSevGuest.group config.users.groups);
|
||||
assertion = (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) || (lib.hasAttr cfgSevGuest.group config.users.groups);
|
||||
message = "Given group does not exist";
|
||||
}
|
||||
];
|
||||
|
||||
users.groups = optionalAttrs (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) {
|
||||
users.groups = lib.optionalAttrs (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) {
|
||||
"${cfgSevGuest.group}" = { };
|
||||
};
|
||||
|
||||
|
@ -1,16 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = mkOption {
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Update the CPU microcode for Intel processors.
|
||||
'';
|
||||
@ -18,12 +13,10 @@ with lib;
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.cpu.intel.updateMicrocode {
|
||||
config = lib.mkIf config.hardware.cpu.intel.updateMicrocode {
|
||||
# Microcode updates must be the first item prepended in the initrd
|
||||
boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
|
||||
boot.initrd.prepend = lib.mkOrder 1 [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
{ config, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.cpu.intel.sgx;
|
||||
defaultPrvGroup = "sgx_prv";
|
||||
in
|
||||
{
|
||||
options.hardware.cpu.intel.sgx.enableDcapCompat = mkOption {
|
||||
options.hardware.cpu.intel.sgx.enableDcapCompat = lib.mkOption {
|
||||
description = ''
|
||||
Whether to enable backward compatibility for SGX software build for the
|
||||
out-of-tree Intel SGX DCAP driver.
|
||||
@ -15,43 +14,43 @@ in
|
||||
`/dev/sgx/enclave` and `/dev/sgx/provision`,
|
||||
respectively.
|
||||
'';
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
options.hardware.cpu.intel.sgx.provision = {
|
||||
enable = mkEnableOption "access to the Intel SGX provisioning device";
|
||||
user = mkOption {
|
||||
enable = lib.mkEnableOption "access to the Intel SGX provisioning device";
|
||||
user = lib.mkOption {
|
||||
description = "Owner to assign to the SGX provisioning device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
};
|
||||
group = mkOption {
|
||||
group = lib.mkOption {
|
||||
description = "Group to assign to the SGX provisioning device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = defaultPrvGroup;
|
||||
};
|
||||
mode = mkOption {
|
||||
mode = lib.mkOption {
|
||||
description = "Mode to set for the SGX provisioning device.";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
default = "0660";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.provision.enable {
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf cfg.provision.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = hasAttr cfg.provision.user config.users.users;
|
||||
assertion = lib.hasAttr cfg.provision.user config.users.users;
|
||||
message = "Given user does not exist";
|
||||
}
|
||||
{
|
||||
assertion = (cfg.provision.group == defaultPrvGroup) || (hasAttr cfg.provision.group config.users.groups);
|
||||
assertion = (cfg.provision.group == defaultPrvGroup) || (lib.hasAttr cfg.provision.group config.users.groups);
|
||||
message = "Given group does not exist";
|
||||
}
|
||||
];
|
||||
|
||||
users.groups = optionalAttrs (cfg.provision.group == defaultPrvGroup) {
|
||||
users.groups = lib.optionalAttrs (cfg.provision.group == defaultPrvGroup) {
|
||||
"${cfg.provision.group}" = { };
|
||||
};
|
||||
|
||||
@ -59,7 +58,7 @@ in
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_provision", OWNER="${user}", GROUP="${group}", MODE="${mode}"
|
||||
'';
|
||||
})
|
||||
(mkIf cfg.enableDcapCompat {
|
||||
(lib.mkIf cfg.enableDcapCompat {
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_enclave", SYMLINK+="sgx/enclave"
|
||||
SUBSYSTEM=="misc", KERNEL=="sgx_provision", SYMLINK+="sgx/provision"
|
||||
|
@ -1,29 +1,26 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.digitalbitbox;
|
||||
in
|
||||
|
||||
{
|
||||
options.hardware.digitalbitbox = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables udev rules for Digital Bitbox devices.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "digitalbitbox" {
|
||||
package = lib.mkPackageOption pkgs "digitalbitbox" {
|
||||
extraDescription = ''
|
||||
This can be used to install a package with udev rules that differ from the defaults.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = [ cfg.package ];
|
||||
};
|
||||
}
|
||||
|
@ -1,19 +1,16 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.ksm;
|
||||
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "hardware" "enableKSM" ] [ "hardware" "ksm" "enable" ])
|
||||
(lib.mkRenamedOptionModule [ "hardware" "enableKSM" ] [ "hardware" "ksm" "enable" ])
|
||||
];
|
||||
|
||||
options.hardware.ksm = {
|
||||
enable = mkEnableOption "Linux kernel Same-Page Merging";
|
||||
sleep = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
enable = lib.mkEnableOption "Linux kernel Same-Page Merging";
|
||||
sleep = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
How many milliseconds ksmd should sleep between scans.
|
||||
@ -22,14 +19,14 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.enable-ksm = {
|
||||
description = "Enable Kernel Same-Page Merging";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script =
|
||||
''
|
||||
echo 1 > /sys/kernel/mm/ksm/run
|
||||
'' + optionalString (cfg.sleep != null)
|
||||
'' + lib.optionalString (cfg.sleep != null)
|
||||
''
|
||||
echo ${toString cfg.sleep} > /sys/kernel/mm/ksm/sleep_millisecs
|
||||
'';
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.ledger;
|
||||
|
||||
in {
|
||||
options.hardware.ledger.enable = mkEnableOption "udev rules for Ledger devices";
|
||||
options.hardware.ledger.enable = lib.mkEnableOption "udev rules for Ledger devices";
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = [ pkgs.ledger-udev-rules ];
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.logitech;
|
||||
|
||||
@ -12,25 +9,25 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "hardware" "logitech" "enable" ] [ "hardware" "logitech" "wireless" "enable" ])
|
||||
(mkRenamedOptionModule [ "hardware" "logitech" "enableGraphical" ] [ "hardware" "logitech" "wireless" "enableGraphical" ])
|
||||
(lib.mkRenamedOptionModule [ "hardware" "logitech" "enable" ] [ "hardware" "logitech" "wireless" "enable" ])
|
||||
(lib.mkRenamedOptionModule [ "hardware" "logitech" "enableGraphical" ] [ "hardware" "logitech" "wireless" "enableGraphical" ])
|
||||
];
|
||||
|
||||
options.hardware.logitech = {
|
||||
|
||||
lcd = {
|
||||
enable = mkEnableOption "support for Logitech LCD Devices";
|
||||
enable = lib.mkEnableOption "support for Logitech LCD Devices";
|
||||
|
||||
startWhenNeeded = mkOption {
|
||||
type = types.bool;
|
||||
startWhenNeeded = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Only run the service when an actual supported device is plugged.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
devices = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "0a07" "c222" "c225" "c227" "c251" ];
|
||||
description = ''
|
||||
List of USB device ids supported by g15daemon.
|
||||
@ -41,10 +38,10 @@ in
|
||||
};
|
||||
|
||||
wireless = {
|
||||
enable = mkEnableOption "support for Logitech Wireless Devices";
|
||||
enable = lib.mkEnableOption "support for Logitech Wireless Devices";
|
||||
|
||||
enableGraphical = mkOption {
|
||||
type = types.bool;
|
||||
enableGraphical = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable graphical support applications.";
|
||||
};
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
meta.maintainers = with maintainers; [ grahamc ];
|
||||
meta.maintainers = with lib.maintainers; [ grahamc ];
|
||||
options = {
|
||||
|
||||
hardware.mcelog = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the Machine Check Exception logger.
|
||||
@ -18,7 +15,7 @@ with lib;
|
||||
|
||||
};
|
||||
|
||||
config = mkIf config.hardware.mcelog.enable {
|
||||
config = lib.mkIf config.hardware.mcelog.enable {
|
||||
systemd = {
|
||||
packages = [ pkgs.mcelog ];
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
kernelVersion = config.boot.kernelPackages.kernel.version;
|
||||
linuxKernelMinVersion = "5.8";
|
||||
@ -11,9 +9,9 @@ let
|
||||
};
|
||||
in
|
||||
{
|
||||
options.networking.wireless.athUserRegulatoryDomain = mkOption {
|
||||
options.networking.wireless.athUserRegulatoryDomain = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
If enabled, sets the ATH_USER_REGD kernel config switch to true to
|
||||
disable the enforcement of EEPROM regulatory restrictions for ath
|
||||
@ -21,9 +19,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf config.networking.wireless.athUserRegulatoryDomain {
|
||||
assertions = singleton {
|
||||
assertion = lessThan 0 (builtins.compareVersions kernelVersion linuxKernelMinVersion);
|
||||
config = lib.mkIf config.networking.wireless.athUserRegulatoryDomain {
|
||||
assertions = lib.singleton {
|
||||
assertion = lib.lessThan 0 (builtins.compareVersions kernelVersion linuxKernelMinVersion);
|
||||
message = "ATH_USER_REGD patch for kernels older than ${linuxKernelMinVersion} not ported yet!";
|
||||
};
|
||||
boot.kernelPatches = [ kernelPatch ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
||||
|
||||
{
|
||||
@ -10,9 +7,9 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
||||
|
||||
options = {
|
||||
|
||||
networking.enableB43Firmware = mkOption {
|
||||
networking.enableB43Firmware = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Turn on this option if you want firmware for the NICs supported by the b43 module.
|
||||
'';
|
||||
@ -23,7 +20,7 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.networking.enableB43Firmware {
|
||||
config = lib.mkIf config.networking.enableB43Firmware {
|
||||
hardware.firmware = [ pkgs.b43Firmware_5_1_138 ];
|
||||
};
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.new-lg4ff;
|
||||
kernelPackages = config.boot.kernelPackages;
|
||||
in {
|
||||
options.hardware.new-lg4ff = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables improved Linux module drivers for Logitech driving wheels.
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.hardware.nitrokey;
|
||||
@ -10,8 +7,8 @@ in
|
||||
|
||||
{
|
||||
options.hardware.nitrokey = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables udev rules for Nitrokey devices. By default grants access
|
||||
@ -21,7 +18,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = [ pkgs.libnitrokey ];
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
####### interface
|
||||
@ -9,8 +6,8 @@ with lib;
|
||||
options = {
|
||||
|
||||
hardware.onlykey = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable OnlyKey device (https://crp.to/p/) support.
|
||||
@ -25,7 +22,7 @@ with lib;
|
||||
|
||||
####### implementation
|
||||
|
||||
config = mkIf config.hardware.onlykey.enable {
|
||||
config = lib.mkIf config.hardware.onlykey.enable {
|
||||
services.udev.extraRules = builtins.readFile ./onlykey.udev;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.openrazer;
|
||||
kernelPackages = config.boot.kernelPackages;
|
||||
@ -51,20 +48,20 @@ in
|
||||
{
|
||||
options = {
|
||||
hardware.openrazer = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
OpenRazer drivers and userspace daemon
|
||||
'';
|
||||
|
||||
verboseLogging = mkOption {
|
||||
type = types.bool;
|
||||
verboseLogging = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable verbose logging. Logs debug messages.
|
||||
'';
|
||||
};
|
||||
|
||||
syncEffectsEnabled = mkOption {
|
||||
type = types.bool;
|
||||
syncEffectsEnabled = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Set the sync effects flag to true so any assignment of
|
||||
@ -72,30 +69,30 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
devicesOffOnScreensaver = mkOption {
|
||||
type = types.bool;
|
||||
devicesOffOnScreensaver = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Turn off the devices when the systems screensaver kicks in.
|
||||
'';
|
||||
};
|
||||
|
||||
batteryNotifier = mkOption {
|
||||
batteryNotifier = lib.mkOption {
|
||||
description = ''
|
||||
Settings for device battery notifications.
|
||||
'';
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Mouse battery notifier.
|
||||
'';
|
||||
};
|
||||
frequency = mkOption {
|
||||
type = types.int;
|
||||
frequency = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 600;
|
||||
description = ''
|
||||
How often battery notifications should be shown (in seconds).
|
||||
@ -103,8 +100,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
percentage = mkOption {
|
||||
type = types.int;
|
||||
percentage = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 33;
|
||||
description = ''
|
||||
At what battery percentage the device should reach before
|
||||
@ -115,8 +112,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
keyStatistics = mkOption {
|
||||
type = types.bool;
|
||||
keyStatistics = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Collects number of keypresses per hour per key used to
|
||||
@ -124,8 +121,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
users = mkOption {
|
||||
type = with types; listOf str;
|
||||
users = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
Usernames to be added to the "openrazer" group, so that they
|
||||
@ -136,10 +133,10 @@ in
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "hardware" "openrazer" "mouseBatteryNotifier" ] [ "hardware" "openrazer" "batteryNotifier" "enable" ])
|
||||
(lib.mkRenamedOptionModule [ "hardware" "openrazer" "mouseBatteryNotifier" ] [ "hardware" "openrazer" "batteryNotifier" "enable" ])
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
boot.extraModulePackages = [ kernelPackages.openrazer ];
|
||||
boot.kernelModules = drivers;
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.opentabletdriver;
|
||||
in
|
||||
@ -9,29 +7,29 @@ in
|
||||
|
||||
options = {
|
||||
hardware.opentabletdriver = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Enable OpenTabletDriver udev rules, user service and blacklist kernel
|
||||
modules known to conflict with OpenTabletDriver.
|
||||
'';
|
||||
};
|
||||
|
||||
blacklistedKernelModules = mkOption {
|
||||
type = types.listOf types.str;
|
||||
blacklistedKernelModules = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "hid-uclogic" "wacom" ];
|
||||
description = ''
|
||||
Blacklist of kernel modules known to conflict with OpenTabletDriver.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "opentabletdriver" { };
|
||||
package = lib.mkPackageOption pkgs "opentabletdriver" { };
|
||||
|
||||
daemon = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to start OpenTabletDriver daemon as a systemd user service.
|
||||
'';
|
||||
@ -40,14 +38,14 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
services.udev.packages = [ cfg.package ];
|
||||
|
||||
boot.blacklistedKernelModules = cfg.blacklistedKernelModules;
|
||||
|
||||
systemd.user.services.opentabletdriver = with pkgs; mkIf cfg.daemon.enable {
|
||||
systemd.user.services.opentabletdriver = with pkgs; lib.mkIf cfg.daemon.enable {
|
||||
description = "Open source, cross-platform, user-mode tablet driver";
|
||||
wantedBy = [ "graphical-session.target" ];
|
||||
partOf = [ "graphical-session.target" ];
|
||||
|
@ -1,53 +1,45 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
pcmciaUtils = pkgs.pcmciaUtils.passthru.function {
|
||||
inherit (config.hardware.pcmcia) firmware config;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
hardware.pcmcia = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable this option to support PCMCIA card.
|
||||
'';
|
||||
};
|
||||
|
||||
firmware = mkOption {
|
||||
type = types.listOf types.path;
|
||||
firmware = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
List of firmware used to handle specific PCMCIA card.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
config = lib.mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
description = ''
|
||||
Path to the configuration file which maps the memory, IRQs
|
||||
and ports used by the PCMCIA hardware.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.pcmcia.enable {
|
||||
config = lib.mkIf config.hardware.pcmcia.enable {
|
||||
|
||||
boot.kernelModules = [ "pcmcia" ];
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.printers;
|
||||
|
||||
ensurePrinter = p: let
|
||||
args = cli.toGNUCommandLineShell {} ({
|
||||
args = lib.cli.toGNUCommandLineShell {} ({
|
||||
p = p.name;
|
||||
v = p.deviceUri;
|
||||
m = p.model;
|
||||
} // optionalAttrs (p.location != null) {
|
||||
} // lib.optionalAttrs (p.location != null) {
|
||||
L = p.location;
|
||||
} // optionalAttrs (p.description != null) {
|
||||
} // lib.optionalAttrs (p.description != null) {
|
||||
D = p.description;
|
||||
} // optionalAttrs (p.ppdOptions != {}) {
|
||||
o = mapAttrsToList (name: value: "${name}=${value}") p.ppdOptions;
|
||||
} // lib.optionalAttrs (p.ppdOptions != {}) {
|
||||
o = lib.mapAttrsToList (name: value: "${name}=${value}") p.ppdOptions;
|
||||
});
|
||||
in ''
|
||||
${pkgs.cups}/bin/lpadmin ${args} -E
|
||||
@ -24,22 +23,22 @@ let
|
||||
'';
|
||||
|
||||
# "graph but not # or /" can't be implemented as regex alone due to missing lookahead support
|
||||
noInvalidChars = str: all (c: c != "#" && c != "/") (stringToCharacters str);
|
||||
printerName = (types.addCheck (types.strMatching "[[:graph:]]+") noInvalidChars)
|
||||
noInvalidChars = str: lib.all (c: c != "#" && c != "/") (lib.stringToCharacters str);
|
||||
printerName = (lib.types.addCheck (lib.types.strMatching "[[:graph:]]+") noInvalidChars)
|
||||
// { description = "printable string without spaces, # and /"; };
|
||||
|
||||
|
||||
in {
|
||||
options = {
|
||||
hardware.printers = {
|
||||
ensureDefaultPrinter = mkOption {
|
||||
type = types.nullOr printerName;
|
||||
ensureDefaultPrinter = lib.mkOption {
|
||||
type = lib.types.nullOr printerName;
|
||||
default = null;
|
||||
description = ''
|
||||
Ensures the named printer is the default CUPS printer / printer queue.
|
||||
'';
|
||||
};
|
||||
ensurePrinters = mkOption {
|
||||
ensurePrinters = lib.mkOption {
|
||||
description = ''
|
||||
Will regularly ensure that the given CUPS printers are configured as declared here.
|
||||
If a printer's options are manually changed afterwards, they will be overwritten eventually.
|
||||
@ -49,9 +48,9 @@ in {
|
||||
Printers not listed here can still be manually configured.
|
||||
'';
|
||||
default = [];
|
||||
type = types.listOf (types.submodule {
|
||||
type = lib.types.listOf (lib.types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
name = lib.mkOption {
|
||||
type = printerName;
|
||||
example = "BrotherHL_Workroom";
|
||||
description = ''
|
||||
@ -59,25 +58,25 @@ in {
|
||||
May contain any printable characters except "/", "#", and space.
|
||||
'';
|
||||
};
|
||||
location = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
location = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "Workroom";
|
||||
description = ''
|
||||
Optional human-readable location.
|
||||
'';
|
||||
};
|
||||
description = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "Brother HL-5140";
|
||||
description = ''
|
||||
Optional human-readable description.
|
||||
'';
|
||||
};
|
||||
deviceUri = mkOption {
|
||||
type = types.str;
|
||||
example = literalExpression ''
|
||||
deviceUri = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = lib.literalExpression ''
|
||||
"ipp://printserver.local/printers/BrotherHL_Workroom"
|
||||
"usb://HP/DESKJET%20940C?serial=CN16E6C364BH"
|
||||
'';
|
||||
@ -86,9 +85,9 @@ in {
|
||||
{command}`lpinfo -v` shows a list of supported device URIs and schemes.
|
||||
'';
|
||||
};
|
||||
model = mkOption {
|
||||
type = types.str;
|
||||
example = literalExpression ''
|
||||
model = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = lib.literalExpression ''
|
||||
"gutenprint.''${lib.versions.majorMinor (lib.getVersion pkgs.gutenprint)}://brother-hl-5140/expert"
|
||||
'';
|
||||
description = ''
|
||||
@ -96,8 +95,8 @@ in {
|
||||
{command}`lpinfo -m` shows a list of supported models.
|
||||
'';
|
||||
};
|
||||
ppdOptions = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
ppdOptions = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
example = {
|
||||
PageSize = "A4";
|
||||
Duplex = "DuplexNoTumble";
|
||||
@ -114,7 +113,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.ensurePrinters != [] && config.services.printing.enable) {
|
||||
config = lib.mkIf (cfg.ensurePrinters != [] && config.services.printing.enable) {
|
||||
systemd.services.ensure-printers = {
|
||||
description = "Ensure NixOS-configured CUPS printers";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
@ -126,13 +125,13 @@ in {
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
|
||||
script = concatStringsSep "\n" [
|
||||
(concatMapStrings ensurePrinter cfg.ensurePrinters)
|
||||
(optionalString (cfg.ensureDefaultPrinter != null)
|
||||
script = lib.concatStringsSep "\n" [
|
||||
(lib.concatMapStrings ensurePrinter cfg.ensurePrinters)
|
||||
(lib.optionalString (cfg.ensureDefaultPrinter != null)
|
||||
(ensureDefaultPrinter cfg.ensureDefaultPrinter))
|
||||
# Note: if cupsd is "stateless" the service can't be stopped,
|
||||
# otherwise the configuration will be wiped on the next start.
|
||||
(optionalString (with config.services.printing; startWhenNeeded && !stateless)
|
||||
(lib.optionalString (with config.services.printing; startWhenNeeded && !stateless)
|
||||
"systemctl stop cups.service")
|
||||
];
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
hpssacli = pkgs.stdenv.mkDerivation rec {
|
||||
pname = "hpssacli";
|
||||
@ -48,13 +45,13 @@ in {
|
||||
|
||||
options = {
|
||||
hardware.raid.HPSmartArray = {
|
||||
enable = mkEnableOption "HP Smart Array kernel modules and CLI utility";
|
||||
enable = lib.mkEnableOption "HP Smart Array kernel modules and CLI utility";
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.raid.HPSmartArray.enable {
|
||||
config = lib.mkIf config.hardware.raid.HPSmartArray.enable {
|
||||
|
||||
boot.initrd.kernelModules = [ "sg" ]; /* hpssacli wants it */
|
||||
boot.initrd.availableKernelModules = [ "hpsa" ];
|
||||
|
@ -1,20 +1,17 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
hardware.sensor.iio = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
description = ''
|
||||
Enable this option to support IIO sensors with iio-sensor-proxy.
|
||||
|
||||
IIO sensors are used for orientation and ambient light
|
||||
sensors on some mobile devices.
|
||||
'';
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
@ -22,7 +19,7 @@ with lib;
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.sensor.iio.enable {
|
||||
config = lib.mkIf config.hardware.sensor.iio.enable {
|
||||
|
||||
boot.initrd.availableKernelModules = [ "hid-sensor-hub" ];
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.hardware.steam-hardware;
|
||||
@ -10,14 +7,14 @@ in
|
||||
|
||||
{
|
||||
options.hardware.steam-hardware = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable udev rules for Steam hardware such as the Steam Controller, other supported controllers and the HTC Vive";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = [
|
||||
pkgs.steamPackages.steam
|
||||
];
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.tuxedo-keyboard;
|
||||
tuxedo-keyboard = config.boot.kernelPackages.tuxedo-keyboard;
|
||||
in
|
||||
{
|
||||
options.hardware.tuxedo-keyboard = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
the tuxedo-keyboard driver.
|
||||
|
||||
To configure the driver, pass the options to the {option}`boot.kernelParams` configuration.
|
||||
@ -27,7 +24,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable
|
||||
config = lib.mkIf cfg.enable
|
||||
{
|
||||
boot.kernelModules = ["tuxedo_keyboard"];
|
||||
boot.extraModulePackages = [ tuxedo-keyboard ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.ubertooth;
|
||||
|
||||
@ -10,17 +7,17 @@ let
|
||||
};
|
||||
in {
|
||||
options.hardware.ubertooth = {
|
||||
enable = mkEnableOption "Ubertooth software and its udev rules";
|
||||
enable = lib.mkEnableOption "Ubertooth software and its udev rules";
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "ubertooth";
|
||||
example = "wheel";
|
||||
description = "Group for Ubertooth's udev rules.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ ubertoothPkg ];
|
||||
|
||||
services.udev.packages = [ ubertoothPkg ];
|
||||
|
@ -1,15 +1,12 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
hardware.usb-modeswitch = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable this option to support certain USB WLAN and WWAN adapters.
|
||||
@ -24,10 +21,10 @@ with lib;
|
||||
###### implementation
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule ["hardware" "usbWwan" ] ["hardware" "usb-modeswitch" ])
|
||||
(lib.mkRenamedOptionModule ["hardware" "usbWwan" ] ["hardware" "usb-modeswitch" ])
|
||||
];
|
||||
|
||||
config = mkIf config.hardware.usb-modeswitch.enable {
|
||||
config = lib.mkIf config.hardware.usb-modeswitch.enable {
|
||||
# Attaches device specific handlers.
|
||||
services.udev.packages = with pkgs; [ usb-modeswitch-data ];
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.hardware.usbStorage.manageStartStop = mkOption {
|
||||
type = types.bool;
|
||||
options.hardware.usbStorage.manageStartStop = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable this option to gracefully spin-down external storage during shutdown.
|
||||
@ -12,7 +10,7 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf config.hardware.usbStorage.manageStartStop {
|
||||
config = lib.mkIf config.hardware.usbStorage.manageStartStop {
|
||||
services.udev.extraRules = ''
|
||||
ACTION=="add|change", SUBSYSTEM=="scsi_disk", DRIVERS=="usb-storage", ATTR{manage_system_start_stop}="1"
|
||||
'';
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.bumblebee;
|
||||
|
||||
@ -26,9 +24,9 @@ in
|
||||
options = {
|
||||
hardware.bumblebee = {
|
||||
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Enable the bumblebee daemon to manage Optimus hybrid video cards.
|
||||
This should power off secondary GPU until its use is requested
|
||||
@ -36,16 +34,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
group = lib.mkOption {
|
||||
default = "wheel";
|
||||
example = "video";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = "Group for bumblebee socket";
|
||||
};
|
||||
|
||||
connectDisplay = mkOption {
|
||||
connectDisplay = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Set to true if you intend to connect your discrete card to a
|
||||
monitor. This option will set up your Nvidia card for EDID
|
||||
@ -55,17 +53,17 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
driver = mkOption {
|
||||
driver = lib.mkOption {
|
||||
default = "nvidia";
|
||||
type = types.enum [ "nvidia" "nouveau" ];
|
||||
type = lib.types.enum [ "nvidia" "nouveau" ];
|
||||
description = ''
|
||||
Set driver used by bumblebeed. Supported are nouveau and nvidia.
|
||||
'';
|
||||
};
|
||||
|
||||
pmMethod = mkOption {
|
||||
pmMethod = lib.mkOption {
|
||||
default = "auto";
|
||||
type = types.enum [ "auto" "bbswitch" "switcheroo" "none" ];
|
||||
type = lib.types.enum [ "auto" "bbswitch" "switcheroo" "none" ];
|
||||
description = ''
|
||||
Set preferred power management method for unused card.
|
||||
'';
|
||||
@ -74,10 +72,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
boot.blacklistedKernelModules = [ "nvidia-drm" "nvidia" "nouveau" ];
|
||||
boot.kernelModules = optional useBbswitch "bbswitch";
|
||||
boot.extraModulePackages = optional useBbswitch kernel.bbswitch ++ optional useNvidia kernel.nvidia_x11.bin;
|
||||
boot.kernelModules = lib.optional useBbswitch "bbswitch";
|
||||
boot.extraModulePackages = lib.optional useBbswitch kernel.bbswitch ++ lib.optional useNvidia kernel.nvidia_x11.bin;
|
||||
|
||||
environment.systemPackages = [ bumblebee primus ];
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.hardware.mwProCapture;
|
||||
@ -12,9 +9,9 @@ in
|
||||
|
||||
{
|
||||
|
||||
options.hardware.mwProCapture.enable = mkEnableOption "the Magewell Pro Capture family kernel module";
|
||||
options.hardware.mwProCapture.enable = lib.mkEnableOption "the Magewell Pro Capture family kernel module";
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
boot.kernelModules = [ "ProCapture" ];
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
enabled = elem "displaylink" config.services.xserver.videoDrivers;
|
||||
enabled = lib.elem "displaylink" config.services.xserver.videoDrivers;
|
||||
|
||||
evdi = config.boot.kernelPackages.evdi;
|
||||
|
||||
@ -16,7 +13,7 @@ in
|
||||
|
||||
{
|
||||
|
||||
config = mkIf enabled {
|
||||
config = lib.mkIf enabled {
|
||||
|
||||
boot.extraModulePackages = [ evdi ];
|
||||
boot.kernelModules = [ "evdi" ];
|
||||
|
@ -1,8 +1,4 @@
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.uvcvideo;
|
||||
@ -19,8 +15,8 @@ in
|
||||
options = {
|
||||
services.uvcvideo.dynctrl = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable {command}`uvcvideo` dynamic controls.
|
||||
@ -31,9 +27,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = types.listOf types.path;
|
||||
example = literalExpression "[ pkgs.tiscamera ]";
|
||||
packages = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
example = lib.literalExpression "[ pkgs.tiscamera ]";
|
||||
description = ''
|
||||
List of packages containing {command}`uvcvideo` dynamic controls
|
||||
rules. All files found in
|
||||
@ -45,12 +41,12 @@ in
|
||||
the dynamic controls from specified packages to the {command}`uvcvideo`
|
||||
driver.
|
||||
'';
|
||||
apply = map getBin;
|
||||
apply = map lib.getBin;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.dynctrl.enable {
|
||||
config = lib.mkIf cfg.dynctrl.enable {
|
||||
|
||||
services.udev.packages = [
|
||||
(uvcdynctrl-udev-rules cfg.dynctrl.packages)
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.hardware.facetimehd;
|
||||
@ -12,12 +9,12 @@ in
|
||||
|
||||
{
|
||||
|
||||
options.hardware.facetimehd.enable = mkEnableOption "the facetimehd kernel module";
|
||||
options.hardware.facetimehd.enable = lib.mkEnableOption "the facetimehd kernel module";
|
||||
|
||||
options.hardware.facetimehd.withCalibration = mkOption {
|
||||
options.hardware.facetimehd.withCalibration = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to include sensor calibration files for facetimehd.
|
||||
This makes colors look much better but is experimental, see
|
||||
@ -26,7 +23,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
boot.kernelModules = [ "facetimehd" ];
|
||||
|
||||
@ -35,7 +32,7 @@ in
|
||||
boot.extraModulePackages = [ kernelPackages.facetimehd ];
|
||||
|
||||
hardware.firmware = [ pkgs.facetimehd-firmware ]
|
||||
++ optional cfg.withCalibration pkgs.facetimehd-calibration;
|
||||
++ lib.optional cfg.withCalibration pkgs.facetimehd-calibration;
|
||||
|
||||
# unload module during suspend/hibernate as it crashes the whole system
|
||||
powerManagement.powerDownCommands = ''
|
||||
|
@ -1,11 +1,9 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{
|
||||
options.hardware.wooting.enable = mkEnableOption ''support for Wooting keyboards.
|
||||
options.hardware.wooting.enable = lib.mkEnableOption ''support for Wooting keyboards.
|
||||
Note that users must be in the "input" group for udev rules to apply'';
|
||||
|
||||
config = mkIf config.hardware.wooting.enable {
|
||||
config = lib.mkIf config.hardware.wooting.enable {
|
||||
environment.systemPackages = [ pkgs.wootility ];
|
||||
services.udev.packages = [ pkgs.wooting-udev-rules ];
|
||||
};
|
||||
|
@ -1,15 +1,13 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.xone;
|
||||
in
|
||||
{
|
||||
options.hardware.xone = {
|
||||
enable = mkEnableOption "the xone driver for Xbox One and Xbox Series X|S accessories";
|
||||
enable = lib.mkEnableOption "the xone driver for Xbox One and Xbox Series X|S accessories";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
boot = {
|
||||
blacklistedKernelModules = [ "xpad" "mt76x2u" ];
|
||||
extraModulePackages = with config.boot.kernelPackages; [ xone ];
|
||||
@ -18,6 +16,6 @@ in
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ rhysmdnz ];
|
||||
maintainers = with lib.maintainers; [ rhysmdnz ];
|
||||
};
|
||||
}
|
||||
|
@ -1,20 +1,18 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.xpadneo;
|
||||
in
|
||||
{
|
||||
options.hardware.xpadneo = {
|
||||
enable = mkEnableOption "the xpadneo driver for Xbox One wireless controllers";
|
||||
enable = lib.mkEnableOption "the xpadneo driver for Xbox One wireless controllers";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
boot = {
|
||||
# Must disable Enhanced Retransmission Mode to support bluetooth pairing
|
||||
# https://wiki.archlinux.org/index.php/Gamepad#Connect_Xbox_Wireless_Controller_with_Bluetooth
|
||||
extraModprobeConfig =
|
||||
mkIf
|
||||
lib.mkIf
|
||||
(config.hardware.bluetooth.enable &&
|
||||
(lib.versionOlder config.boot.kernelPackages.kernel.version "5.12"))
|
||||
"options bluetooth disable_ertm=1";
|
||||
@ -25,6 +23,6 @@ in
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ kira-bruneau ];
|
||||
maintainers = with lib.maintainers; [ kira-bruneau ];
|
||||
};
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.i18n.inputMethod;
|
||||
|
||||
allowedTypes = types.enum [ "ibus" "fcitx5" "nabi" "uim" "hime" "kime" ];
|
||||
allowedTypes = lib.types.enum [ "ibus" "fcitx5" "nabi" "uim" "hime" "kime" ];
|
||||
|
||||
gtk2_cache = pkgs.runCommand "gtk2-immodule.cache"
|
||||
{ preferLocalBuild = true;
|
||||
@ -30,22 +28,22 @@ in
|
||||
{
|
||||
options.i18n = {
|
||||
inputMethod = {
|
||||
enable = mkEnableOption "an additional input method type" // {
|
||||
enable = lib.mkEnableOption "an additional input method type" // {
|
||||
default = cfg.enabled != null;
|
||||
defaultText = literalMD "`true` if the deprecated option `enabled` is set, false otherwise";
|
||||
defaultText = lib.literalMD "`true` if the deprecated option `enabled` is set, false otherwise";
|
||||
};
|
||||
|
||||
enabled = mkOption {
|
||||
type = types.nullOr allowedTypes;
|
||||
enabled = lib.mkOption {
|
||||
type = lib.types.nullOr allowedTypes;
|
||||
default = null;
|
||||
example = "fcitx5";
|
||||
description = "Deprecated - use `type` and `enable = true` instead";
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.nullOr allowedTypes;
|
||||
type = lib.mkOption {
|
||||
type = lib.types.nullOr allowedTypes;
|
||||
default = cfg.enabled;
|
||||
defaultText = literalMD "The value of the deprecated option `enabled`, defaulting to null";
|
||||
defaultText = lib.literalMD "The value of the deprecated option `enabled`, defaulting to null";
|
||||
example = "fcitx5";
|
||||
description = ''
|
||||
Select the enabled input method. Input methods is a software to input symbols that are not available on standard input devices.
|
||||
@ -63,9 +61,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
package = lib.mkOption {
|
||||
internal = true;
|
||||
type = types.nullOr types.path;
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
The input method method package.
|
||||
@ -74,8 +72,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = optional (cfg.enabled != null) "i18n.inputMethod.enabled will be removed in a future release. Please use .type, and .enable = true instead";
|
||||
config = lib.mkIf cfg.enable {
|
||||
warnings = lib.optional (cfg.enabled != null) "i18n.inputMethod.enabled will be removed in a future release. Please use .type, and .enable = true instead";
|
||||
environment.systemPackages = [ cfg.package gtk2_cache gtk3_cache ];
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
imcfg = config.i18n.inputMethod;
|
||||
cfg = imcfg.fcitx5;
|
||||
@ -14,35 +11,35 @@ in
|
||||
{
|
||||
options = {
|
||||
i18n.inputMethod.fcitx5 = {
|
||||
addons = mkOption {
|
||||
type = with types; listOf package;
|
||||
addons = lib.mkOption {
|
||||
type = with lib.types; listOf package;
|
||||
default = [ ];
|
||||
example = literalExpression "with pkgs; [ fcitx5-rime ]";
|
||||
example = lib.literalExpression "with pkgs; [ fcitx5-rime ]";
|
||||
description = ''
|
||||
Enabled Fcitx5 addons.
|
||||
'';
|
||||
};
|
||||
waylandFrontend = mkOption {
|
||||
type = types.bool;
|
||||
waylandFrontend = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use the Wayland input method frontend.
|
||||
See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland).
|
||||
'';
|
||||
};
|
||||
plasma6Support = mkOption {
|
||||
type = types.bool;
|
||||
plasma6Support = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.services.desktopManager.plasma6.enable;
|
||||
defaultText = literalExpression "config.services.desktopManager.plasma6.enable";
|
||||
defaultText = lib.literalExpression "config.services.desktopManager.plasma6.enable";
|
||||
description = ''
|
||||
Use qt6 versions of fcitx5 packages.
|
||||
Required for configuring fcitx5 in KDE System Settings.
|
||||
'';
|
||||
};
|
||||
quickPhrase = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
quickPhrase = lib.mkOption {
|
||||
type = with lib.types; attrsOf str;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
smile = "(・∀・)";
|
||||
angry = "( ̄ー ̄)";
|
||||
@ -50,10 +47,10 @@ in
|
||||
'';
|
||||
description = "Quick phrases.";
|
||||
};
|
||||
quickPhraseFiles = mkOption {
|
||||
type = with types; attrsOf path;
|
||||
quickPhraseFiles = lib.mkOption {
|
||||
type = with lib.types; attrsOf path;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
words = ./words.mb;
|
||||
numbers = ./numbers.mb;
|
||||
@ -87,7 +84,7 @@ in
|
||||
The addon configures in `conf` folder in ini format with global sections.
|
||||
Each item is written to the corresponding file.
|
||||
'';
|
||||
example = literalExpression "{ pinyin.globalSection.EmojiEnabled = \"True\"; }";
|
||||
example = lib.literalExpression "{ pinyin.globalSection.EmojiEnabled = \"True\"; }";
|
||||
};
|
||||
};
|
||||
ignoreUserConfig = lib.mkOption {
|
||||
@ -103,12 +100,12 @@ in
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx5" "enableRimeData" ] ''
|
||||
(lib.mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx5" "enableRimeData" ] ''
|
||||
RIME data is now included in `fcitx5-rime` by default, and can be customized using `fcitx5-rime.override { rimeDataPkgs = ...; }`
|
||||
'')
|
||||
];
|
||||
|
||||
config = mkIf (imcfg.enable && imcfg.type == "fcitx5") {
|
||||
config = lib.mkIf (imcfg.enable && imcfg.type == "fcitx5") {
|
||||
i18n.inputMethod.package = fcitx5Package;
|
||||
|
||||
i18n.inputMethod.fcitx5.addons = lib.optionals (cfg.quickPhrase != { }) [
|
||||
@ -122,15 +119,15 @@ in
|
||||
];
|
||||
environment.etc =
|
||||
let
|
||||
optionalFile = p: f: v: lib.optionalAttrs (v != { }) {
|
||||
lib.optionalFile = p: f: v: lib.optionalAttrs (v != { }) {
|
||||
"xdg/fcitx5/${p}".text = f v;
|
||||
};
|
||||
in
|
||||
lib.attrsets.mergeAttrsList [
|
||||
(optionalFile "config" (lib.generators.toINI { }) cfg.settings.globalOptions)
|
||||
(optionalFile "profile" (lib.generators.toINI { }) cfg.settings.inputMethod)
|
||||
(lib.optionalFile "config" (lib.generators.toINI { }) cfg.settings.globalOptions)
|
||||
(lib.optionalFile "profile" (lib.generators.toINI { }) cfg.settings.inputMethod)
|
||||
(lib.concatMapAttrs
|
||||
(name: value: optionalFile
|
||||
(name: value: lib.optionalFile
|
||||
"conf/${name}.conf"
|
||||
(lib.generators.toINIWithGlobalSection { })
|
||||
value)
|
||||
|
@ -1348,6 +1348,7 @@
|
||||
./services/system/systembus-notify.nix
|
||||
./services/system/systemd-lock-handler.nix
|
||||
./services/system/uptimed.nix
|
||||
./services/system/userborn.nix
|
||||
./services/system/zram-generator.nix
|
||||
./services/torrent/deluge.nix
|
||||
./services/torrent/flexget.nix
|
||||
|
@ -12,7 +12,7 @@
|
||||
# Remove perl from activation
|
||||
boot.initrd.systemd.enable = lib.mkDefault true;
|
||||
system.etc.overlay.enable = lib.mkDefault true;
|
||||
systemd.sysusers.enable = lib.mkDefault true;
|
||||
services.userborn.enable = lib.mkDefault true;
|
||||
|
||||
# Random perl remnants
|
||||
system.disableInstallerTools = lib.mkDefault true;
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.services.libinput;
|
||||
|
||||
xorgBool = v: if v then "on" else "off";
|
||||
|
||||
mkConfigForDevice = deviceType: {
|
||||
dev = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
dev = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/dev/input/event0";
|
||||
description = ''
|
||||
@ -17,8 +14,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelProfile = mkOption {
|
||||
type = types.enum [ "flat" "adaptive" "custom" ];
|
||||
accelProfile = lib.mkOption {
|
||||
type = lib.types.enum [ "flat" "adaptive" "custom" ];
|
||||
default = "adaptive";
|
||||
example = "flat";
|
||||
description = ''
|
||||
@ -36,8 +33,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelSpeed = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
accelSpeed = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "-0.5";
|
||||
description = ''
|
||||
@ -46,8 +43,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelPointsFallback = mkOption {
|
||||
type = types.nullOr (types.listOf types.number);
|
||||
accelPointsFallback = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.number);
|
||||
default = null;
|
||||
example = [ 0.0 1.0 2.4 2.5 ];
|
||||
description = ''
|
||||
@ -56,8 +53,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelPointsMotion = mkOption {
|
||||
type = types.nullOr (types.listOf types.number);
|
||||
accelPointsMotion = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.number);
|
||||
default = null;
|
||||
example = [ 0.0 1.0 2.4 2.5 ];
|
||||
description = ''
|
||||
@ -66,8 +63,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelPointsScroll = mkOption {
|
||||
type = types.nullOr (types.listOf types.number);
|
||||
accelPointsScroll = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.number);
|
||||
default = null;
|
||||
example = [ 0.0 1.0 2.4 2.5 ];
|
||||
description = ''
|
||||
@ -76,8 +73,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelStepFallback = mkOption {
|
||||
type = types.nullOr types.number;
|
||||
accelStepFallback = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.number;
|
||||
default = null;
|
||||
example = 0.1;
|
||||
description = ''
|
||||
@ -87,8 +84,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelStepMotion = mkOption {
|
||||
type = types.nullOr types.number;
|
||||
accelStepMotion = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.number;
|
||||
default = null;
|
||||
example = 0.1;
|
||||
description = ''
|
||||
@ -98,8 +95,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
accelStepScroll = mkOption {
|
||||
type = types.nullOr types.number;
|
||||
accelStepScroll = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.number;
|
||||
default = null;
|
||||
example = 0.1;
|
||||
description = ''
|
||||
@ -109,8 +106,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
buttonMapping = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
buttonMapping = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "1 6 3 4 5 0 7";
|
||||
description = ''
|
||||
@ -123,8 +120,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
calibrationMatrix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
calibrationMatrix = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "0.5 0 0 0 0.8 0.1 0 0 1";
|
||||
description = ''
|
||||
@ -133,8 +130,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
clickMethod = mkOption {
|
||||
type = types.nullOr (types.enum [ "none" "buttonareas" "clickfinger" ]);
|
||||
clickMethod = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.enum [ "none" "buttonareas" "clickfinger" ]);
|
||||
default = null;
|
||||
example = "buttonareas";
|
||||
description = ''
|
||||
@ -145,14 +142,14 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
leftHanded = mkOption {
|
||||
type = types.bool;
|
||||
leftHanded = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enables left-handed button orientation, i.e. swapping left and right buttons.";
|
||||
};
|
||||
|
||||
middleEmulation = mkOption {
|
||||
type = types.bool;
|
||||
middleEmulation = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enables middle button emulation. When enabled, pressing the left and right buttons
|
||||
@ -160,14 +157,14 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
naturalScrolling = mkOption {
|
||||
type = types.bool;
|
||||
naturalScrolling = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enables or disables natural scrolling behavior.";
|
||||
};
|
||||
|
||||
scrollButton = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
scrollButton = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
example = 1;
|
||||
description = ''
|
||||
@ -176,8 +173,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
scrollMethod = mkOption {
|
||||
type = types.enum [ "twofinger" "edge" "button" "none" ];
|
||||
scrollMethod = lib.mkOption {
|
||||
type = lib.types.enum [ "twofinger" "edge" "button" "none" ];
|
||||
default = "twofinger";
|
||||
example = "edge";
|
||||
description = ''
|
||||
@ -186,8 +183,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
horizontalScrolling = mkOption {
|
||||
type = types.bool;
|
||||
horizontalScrolling = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enables or disables horizontal scrolling. When disabled, this driver will discard any
|
||||
@ -196,8 +193,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
sendEventsMode = mkOption {
|
||||
type = types.enum [ "disabled" "enabled" "disabled-on-external-mouse" ];
|
||||
sendEventsMode = lib.mkOption {
|
||||
type = lib.types.enum [ "disabled" "enabled" "disabled-on-external-mouse" ];
|
||||
default = "enabled";
|
||||
example = "disabled";
|
||||
description = ''
|
||||
@ -206,24 +203,24 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
tapping = mkOption {
|
||||
type = types.bool;
|
||||
tapping = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enables or disables tap-to-click behavior.
|
||||
'';
|
||||
};
|
||||
|
||||
tappingButtonMap = mkOption {
|
||||
type = types.nullOr (types.enum [ "lrm" "lmr" ]);
|
||||
tappingButtonMap = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.enum [ "lrm" "lmr" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
Set the button mapping for 1/2/3-finger taps to left/right/middle or left/middle/right, respectively.
|
||||
'';
|
||||
};
|
||||
|
||||
tappingDragLock = mkOption {
|
||||
type = types.bool;
|
||||
tappingDragLock = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enables or disables drag lock during tapping behavior. When enabled, a finger up during tap-
|
||||
@ -232,8 +229,8 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
transformationMatrix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
transformationMatrix = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "0.5 0 0 0 0.8 0.1 0 0 1";
|
||||
description = ''
|
||||
@ -242,16 +239,16 @@ let cfg = config.services.libinput;
|
||||
'';
|
||||
};
|
||||
|
||||
disableWhileTyping = mkOption {
|
||||
type = types.bool;
|
||||
disableWhileTyping = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Disable input method while typing.
|
||||
'';
|
||||
};
|
||||
|
||||
additionalOptions = mkOption {
|
||||
type = types.lines;
|
||||
additionalOptions = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example =
|
||||
''
|
||||
@ -269,28 +266,28 @@ let cfg = config.services.libinput;
|
||||
Identifier "libinput ${deviceType} configuration"
|
||||
MatchDriver "libinput"
|
||||
MatchIs${matchIs} "${xorgBool true}"
|
||||
${optionalString (cfg.${deviceType}.dev != null) ''MatchDevicePath "${cfg.${deviceType}.dev}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.dev != null) ''MatchDevicePath "${cfg.${deviceType}.dev}"''}
|
||||
Option "AccelProfile" "${cfg.${deviceType}.accelProfile}"
|
||||
${optionalString (cfg.${deviceType}.accelSpeed != null) ''Option "AccelSpeed" "${cfg.${deviceType}.accelSpeed}"''}
|
||||
${optionalString (cfg.${deviceType}.accelPointsFallback != null) ''Option "AccelPointsFallback" "${toString cfg.${deviceType}.accelPointsFallback}"''}
|
||||
${optionalString (cfg.${deviceType}.accelPointsMotion != null) ''Option "AccelPointsMotion" "${toString cfg.${deviceType}.accelPointsMotion}"''}
|
||||
${optionalString (cfg.${deviceType}.accelPointsScroll != null) ''Option "AccelPointsScroll" "${toString cfg.${deviceType}.accelPointsScroll}"''}
|
||||
${optionalString (cfg.${deviceType}.accelStepFallback != null) ''Option "AccelStepFallback" "${toString cfg.${deviceType}.accelStepFallback}"''}
|
||||
${optionalString (cfg.${deviceType}.accelStepMotion != null) ''Option "AccelStepMotion" "${toString cfg.${deviceType}.accelStepMotion}"''}
|
||||
${optionalString (cfg.${deviceType}.accelStepScroll != null) ''Option "AccelStepScroll" "${toString cfg.${deviceType}.accelStepScroll}"''}
|
||||
${optionalString (cfg.${deviceType}.buttonMapping != null) ''Option "ButtonMapping" "${cfg.${deviceType}.buttonMapping}"''}
|
||||
${optionalString (cfg.${deviceType}.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.${deviceType}.calibrationMatrix}"''}
|
||||
${optionalString (cfg.${deviceType}.transformationMatrix != null) ''Option "TransformationMatrix" "${cfg.${deviceType}.transformationMatrix}"''}
|
||||
${optionalString (cfg.${deviceType}.clickMethod != null) ''Option "ClickMethod" "${cfg.${deviceType}.clickMethod}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelSpeed != null) ''Option "AccelSpeed" "${cfg.${deviceType}.accelSpeed}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelPointsFallback != null) ''Option "AccelPointsFallback" "${toString cfg.${deviceType}.accelPointsFallback}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelPointsMotion != null) ''Option "AccelPointsMotion" "${toString cfg.${deviceType}.accelPointsMotion}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelPointsScroll != null) ''Option "AccelPointsScroll" "${toString cfg.${deviceType}.accelPointsScroll}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelStepFallback != null) ''Option "AccelStepFallback" "${toString cfg.${deviceType}.accelStepFallback}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelStepMotion != null) ''Option "AccelStepMotion" "${toString cfg.${deviceType}.accelStepMotion}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.accelStepScroll != null) ''Option "AccelStepScroll" "${toString cfg.${deviceType}.accelStepScroll}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.buttonMapping != null) ''Option "ButtonMapping" "${cfg.${deviceType}.buttonMapping}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.${deviceType}.calibrationMatrix}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.transformationMatrix != null) ''Option "TransformationMatrix" "${cfg.${deviceType}.transformationMatrix}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.clickMethod != null) ''Option "ClickMethod" "${cfg.${deviceType}.clickMethod}"''}
|
||||
Option "LeftHanded" "${xorgBool cfg.${deviceType}.leftHanded}"
|
||||
Option "MiddleEmulation" "${xorgBool cfg.${deviceType}.middleEmulation}"
|
||||
Option "NaturalScrolling" "${xorgBool cfg.${deviceType}.naturalScrolling}"
|
||||
${optionalString (cfg.${deviceType}.scrollButton != null) ''Option "ScrollButton" "${toString cfg.${deviceType}.scrollButton}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.scrollButton != null) ''Option "ScrollButton" "${toString cfg.${deviceType}.scrollButton}"''}
|
||||
Option "ScrollMethod" "${cfg.${deviceType}.scrollMethod}"
|
||||
Option "HorizontalScrolling" "${xorgBool cfg.${deviceType}.horizontalScrolling}"
|
||||
Option "SendEventsMode" "${cfg.${deviceType}.sendEventsMode}"
|
||||
Option "Tapping" "${xorgBool cfg.${deviceType}.tapping}"
|
||||
${optionalString (cfg.${deviceType}.tappingButtonMap != null) ''Option "TappingButtonMap" "${cfg.${deviceType}.tappingButtonMap}"''}
|
||||
${lib.optionalString (cfg.${deviceType}.tappingButtonMap != null) ''Option "TappingButtonMap" "${cfg.${deviceType}.tappingButtonMap}"''}
|
||||
Option "TappingDragLock" "${xorgBool cfg.${deviceType}.tappingDragLock}"
|
||||
Option "DisableWhileTyping" "${xorgBool cfg.${deviceType}.disableWhileTyping}"
|
||||
${cfg.${deviceType}.additionalOptions}
|
||||
@ -298,7 +295,7 @@ let cfg = config.services.libinput;
|
||||
in {
|
||||
|
||||
imports =
|
||||
(map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "libinput" "touchpad" option ]) [
|
||||
(map (option: lib.mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "libinput" "touchpad" option ]) [
|
||||
"accelProfile"
|
||||
"accelSpeed"
|
||||
"buttonMapping"
|
||||
@ -318,15 +315,15 @@ in {
|
||||
"disableWhileTyping"
|
||||
"additionalOptions"
|
||||
]) ++ [
|
||||
(mkRenamedOptionModule [ "services" "xserver" "libinput" "enable" ] [ "services" "libinput" "enable" ])
|
||||
(mkRenamedOptionModule [ "services" "xserver" "libinput" "mouse" ] [ "services" "libinput" "mouse" ])
|
||||
(mkRenamedOptionModule [ "services" "xserver" "libinput" "touchpad" ] [ "services" "libinput" "touchpad" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "xserver" "libinput" "enable" ] [ "services" "libinput" "enable" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "xserver" "libinput" "mouse" ] [ "services" "libinput" "mouse" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "xserver" "libinput" "touchpad" ] [ "services" "libinput" "touchpad" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
|
||||
services.libinput = {
|
||||
enable = mkEnableOption "libinput" // {
|
||||
enable = lib.mkEnableOption "libinput" // {
|
||||
default = config.services.xserver.enable;
|
||||
defaultText = lib.literalExpression "config.services.xserver.enable";
|
||||
};
|
||||
@ -336,7 +333,7 @@ in {
|
||||
};
|
||||
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
services.xserver.modules = [ pkgs.xorg.xf86inputlibinput ];
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.clamsmtp;
|
||||
clamdSocket = "/run/clamav/clamd.ctl"; # See services/security/clamav.nix
|
||||
@ -9,17 +7,17 @@ in
|
||||
##### interface
|
||||
options = {
|
||||
services.clamsmtp = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable clamsmtp.";
|
||||
};
|
||||
|
||||
instances = mkOption {
|
||||
instances = lib.mkOption {
|
||||
description = "Instances of clamsmtp to run.";
|
||||
type = types.listOf (types.submodule { options = {
|
||||
action = mkOption {
|
||||
type = types.enum [ "bounce" "drop" "pass" ];
|
||||
type = lib.types.listOf (lib.types.submodule { options = {
|
||||
action = lib.mkOption {
|
||||
type = lib.types.enum [ "bounce" "drop" "pass" ];
|
||||
default = "drop";
|
||||
description = ''
|
||||
Action to take when a virus is detected.
|
||||
@ -29,8 +27,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
header = mkOption {
|
||||
type = types.str;
|
||||
header = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
example = "X-Virus-Scanned: ClamAV using ClamSMTP";
|
||||
description = ''
|
||||
@ -39,8 +37,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
keepAlives = mkOption {
|
||||
type = types.int;
|
||||
keepAlives = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 0;
|
||||
description = ''
|
||||
Number of seconds to wait between each NOOP sent to the sending
|
||||
@ -51,8 +49,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
listen = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "127.0.0.1:10025";
|
||||
description = ''
|
||||
Address to wait for incoming SMTP connections on. See
|
||||
@ -60,8 +58,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
quarantine = mkOption {
|
||||
type = types.bool;
|
||||
quarantine = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to quarantine files that contain viruses by leaving them
|
||||
@ -69,22 +67,22 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
maxConnections = mkOption {
|
||||
type = types.int;
|
||||
maxConnections = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 64;
|
||||
description = "Maximum number of connections to accept at once.";
|
||||
};
|
||||
|
||||
outAddress = mkOption {
|
||||
type = types.str;
|
||||
outAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Address of the SMTP server to send email to once it has been
|
||||
scanned.
|
||||
'';
|
||||
};
|
||||
|
||||
tempDirectory = mkOption {
|
||||
type = types.str;
|
||||
tempDirectory = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/tmp";
|
||||
description = ''
|
||||
Temporary directory that needs to be accessible to both clamd
|
||||
@ -92,20 +90,20 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
timeout = mkOption {
|
||||
type = types.int;
|
||||
timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 180;
|
||||
description = "Time-out for network connections.";
|
||||
};
|
||||
|
||||
transparentProxy = mkOption {
|
||||
type = types.bool;
|
||||
transparentProxy = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable clamsmtp's transparent proxy support.";
|
||||
};
|
||||
|
||||
virusAction = mkOption {
|
||||
type = with types; nullOr path;
|
||||
virusAction = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
Command to run when a virus is found. Please see VIRUS ACTION in
|
||||
@ -113,8 +111,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
xClient = mkOption {
|
||||
type = types.bool;
|
||||
xClient = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Send the XCLIENT command to the receiving server, for forwarding
|
||||
@ -143,19 +141,19 @@ in
|
||||
TimeOut: ${toString conf.timeout}
|
||||
TransparentProxy: ${if conf.transparentProxy then "on" else "off"}
|
||||
User: clamav
|
||||
${optionalString (conf.virusAction != null) "VirusAction: ${conf.virusAction}"}
|
||||
${lib.optionalString (conf.virusAction != null) "VirusAction: ${conf.virusAction}"}
|
||||
XClient: ${if conf.xClient then "on" else "off"}
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = config.services.clamav.daemon.enable;
|
||||
message = "clamsmtp requires clamav to be enabled";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services = listToAttrs (imap1 (i: conf:
|
||||
nameValuePair "clamsmtp-${toString i}" {
|
||||
systemd.services = lib.listToAttrs (lib.imap1 (i: conf:
|
||||
lib.nameValuePair "clamsmtp-${toString i}" {
|
||||
description = "ClamSMTP instance ${toString i}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = "exec ${pkgs.clamsmtp}/bin/clamsmtpd -f ${configfile conf}";
|
||||
|
@ -1,39 +1,36 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.davmail;
|
||||
|
||||
configType = with types;
|
||||
configType = with lib.types;
|
||||
oneOf [ (attrsOf configType) str int bool ] // {
|
||||
description = "davmail config type (str, int, bool or attribute set thereof)";
|
||||
};
|
||||
|
||||
toStr = val: if isBool val then boolToString val else toString val;
|
||||
toStr = val: if lib.isBool val then lib.boolToString val else toString val;
|
||||
|
||||
linesForAttrs = attrs: concatMap (name: let value = attrs.${name}; in
|
||||
if isAttrs value
|
||||
linesForAttrs = attrs: lib.concatMap (name: let value = attrs.${name}; in
|
||||
if lib.isAttrs value
|
||||
then map (line: name + "." + line) (linesForAttrs value)
|
||||
else [ "${name}=${toStr value}" ]
|
||||
) (attrNames attrs);
|
||||
) (lib.attrNames attrs);
|
||||
|
||||
configFile = pkgs.writeText "davmail.properties" (concatStringsSep "\n" (linesForAttrs cfg.config));
|
||||
configFile = pkgs.writeText "davmail.properties" (lib.concatStringsSep "\n" (linesForAttrs cfg.config));
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options.services.davmail = {
|
||||
enable = mkEnableOption "davmail, an MS Exchange gateway";
|
||||
enable = lib.mkEnableOption "davmail, an MS Exchange gateway";
|
||||
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Outlook Web Access URL to access the exchange server, i.e. the base webmail URL.";
|
||||
example = "https://outlook.office365.com/EWS/Exchange.asmx";
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
config = lib.mkOption {
|
||||
type = configType;
|
||||
default = {};
|
||||
description = ''
|
||||
@ -42,7 +39,7 @@ in
|
||||
and <http://davmail.sourceforge.net/advanced.html>
|
||||
for details on supported values.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
davmail.allowRemote = true;
|
||||
davmail.imapPort = 55555;
|
||||
@ -56,10 +53,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
services.davmail.config = {
|
||||
davmail = mapAttrs (name: mkDefault) {
|
||||
davmail = lib.mapAttrs (name: lib.mkDefault) {
|
||||
server = true;
|
||||
disableUpdateCheck = true;
|
||||
logFilePath = "/var/log/davmail/davmail.log";
|
||||
@ -73,10 +70,10 @@ in
|
||||
smtpPort = 1025;
|
||||
};
|
||||
log4j = {
|
||||
logger.davmail = mkDefault "WARN";
|
||||
logger.httpclient.wire = mkDefault "WARN";
|
||||
logger.org.apache.commons.httpclient = mkDefault "WARN";
|
||||
rootLogger = mkDefault "WARN";
|
||||
logger.davmail = lib.mkDefault "WARN";
|
||||
logger.httpclient.wire = lib.mkDefault "WARN";
|
||||
logger.org.apache.commons.httpclient = lib.mkDefault "WARN";
|
||||
rootLogger = lib.mkDefault "WARN";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.dkimproxy-out;
|
||||
keydir = "/var/lib/dkimproxy-out";
|
||||
@ -11,8 +9,8 @@ in
|
||||
##### interface
|
||||
options = {
|
||||
services.dkimproxy-out = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable dkimproxy_out.
|
||||
@ -22,26 +20,26 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
listen = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "127.0.0.1:10027";
|
||||
description = "Address:port DKIMproxy should listen on.";
|
||||
};
|
||||
|
||||
relay = mkOption {
|
||||
type = types.str;
|
||||
relay = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "127.0.0.1:10028";
|
||||
description = "Address:port DKIMproxy should forward mail to.";
|
||||
};
|
||||
|
||||
domains = mkOption {
|
||||
type = with types; listOf str;
|
||||
domains = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
example = [ "example.org" "example.com" ];
|
||||
description = "List of domains DKIMproxy can sign for.";
|
||||
};
|
||||
|
||||
selector = mkOption {
|
||||
type = types.str;
|
||||
selector = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "selector1";
|
||||
description = ''
|
||||
The selector to use for DKIM key identification.
|
||||
@ -53,8 +51,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
keySize = mkOption {
|
||||
type = types.int;
|
||||
keySize = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2048;
|
||||
description = ''
|
||||
Size of the RSA key to use to sign outgoing emails. Note that the
|
||||
@ -75,7 +73,7 @@ in
|
||||
listen ${cfg.listen}
|
||||
relay ${cfg.relay}
|
||||
|
||||
domain ${concatStringsSep "," cfg.domains}
|
||||
domain ${lib.concatStringsSep "," cfg.domains}
|
||||
selector ${cfg.selector}
|
||||
|
||||
signature dkim(c=relaxed/relaxed)
|
||||
@ -83,7 +81,7 @@ in
|
||||
keyfile ${privkey}
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
lib.mkIf cfg.enable {
|
||||
users.groups.dkimproxy-out = {};
|
||||
users.users.dkimproxy-out = {
|
||||
description = "DKIMproxy_out daemon";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.dspam;
|
||||
@ -19,7 +16,7 @@ let
|
||||
SystemLog on
|
||||
UserLog on
|
||||
|
||||
${optionalString (cfg.domainSocket != null) ''
|
||||
${lib.optionalString (cfg.domainSocket != null) ''
|
||||
ServerDomainSocketPath "${cfg.domainSocket}"
|
||||
ClientHost "${cfg.domainSocket}"
|
||||
''}
|
||||
@ -35,44 +32,44 @@ in {
|
||||
|
||||
services.dspam = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the dspam spam filter.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "dspam";
|
||||
description = "User for the dspam daemon.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "dspam";
|
||||
description = "Group for the dspam daemon.";
|
||||
};
|
||||
|
||||
storageDriver = mkOption {
|
||||
type = types.str;
|
||||
storageDriver = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "hash";
|
||||
description = "Storage driver backend to use for dspam.";
|
||||
};
|
||||
|
||||
domainSocket = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
domainSocket = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = defaultSock;
|
||||
description = "Path to local domain socket which is used for communication with the daemon. Set to null to disable UNIX socket.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = "Additional dspam configuration.";
|
||||
};
|
||||
|
||||
maintenanceInterval = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
maintenanceInterval = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "If set, maintenance script will be run at specified (in systemd.timer format) interval";
|
||||
};
|
||||
@ -84,16 +81,16 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
users.users = optionalAttrs (cfg.user == "dspam") {
|
||||
users.users = lib.optionalAttrs (cfg.user == "dspam") {
|
||||
dspam = {
|
||||
group = cfg.group;
|
||||
uid = config.ids.uids.dspam;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == "dspam") {
|
||||
users.groups = lib.optionalAttrs (cfg.group == "dspam") {
|
||||
dspam.gid = config.ids.gids.dspam;
|
||||
};
|
||||
|
||||
@ -111,8 +108,8 @@ in {
|
||||
ExecStart = "${dspam}/bin/dspam --daemon --nofork";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
RuntimeDirectory = optional (cfg.domainSocket == defaultSock) "dspam";
|
||||
RuntimeDirectoryMode = optional (cfg.domainSocket == defaultSock) "0750";
|
||||
RuntimeDirectory = lib.optional (cfg.domainSocket == defaultSock) "dspam";
|
||||
RuntimeDirectoryMode = lib.optional (cfg.domainSocket == defaultSock) "0750";
|
||||
StateDirectory = "dspam";
|
||||
StateDirectoryMode = "0750";
|
||||
LogsDirectory = "dspam";
|
||||
@ -124,7 +121,7 @@ in {
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf (cfg.maintenanceInterval != null) {
|
||||
(lib.mkIf (cfg.maintenanceInterval != null) {
|
||||
systemd.timers.dspam-maintenance = {
|
||||
description = "Timer for dspam maintenance script";
|
||||
wantedBy = [ "timers.target" ];
|
||||
|
@ -1,16 +1,13 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.goeland;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
options.services.goeland = {
|
||||
enable = mkEnableOption "goeland, an alternative to rss2email";
|
||||
enable = lib.mkEnableOption "goeland, an alternative to rss2email";
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration of goeland.
|
||||
See the [example config file](https://github.com/slurdge/goeland/blob/master/cmd/asset/config.default.toml) for the available options.
|
||||
@ -18,14 +15,14 @@ in
|
||||
default = { };
|
||||
type = tomlFormat.type;
|
||||
};
|
||||
schedule = mkOption {
|
||||
type = types.str;
|
||||
schedule = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "12h";
|
||||
example = "Mon, 00:00:00";
|
||||
description = "How often to run goeland, in systemd time format.";
|
||||
};
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
stateDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/goeland";
|
||||
description = ''
|
||||
The data directory for goeland where the database will reside if using the unseen filter.
|
||||
@ -36,17 +33,17 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.goeland.settings.database = "${cfg.stateDir}/goeland.db";
|
||||
|
||||
systemd.services.goeland = {
|
||||
serviceConfig = let confFile = tomlFormat.generate "config.toml" cfg.settings; in mkMerge [
|
||||
serviceConfig = let confFile = tomlFormat.generate "config.toml" cfg.settings; in lib.mkMerge [
|
||||
{
|
||||
ExecStart = "${pkgs.goeland}/bin/goeland run -c ${confFile}";
|
||||
User = "goeland";
|
||||
Group = "goeland";
|
||||
}
|
||||
(mkIf (cfg.stateDir == "/var/lib/goeland") {
|
||||
(lib.mkIf (cfg.stateDir == "/var/lib/goeland") {
|
||||
StateDirectory = "goeland";
|
||||
StateDirectoryMode = "0750";
|
||||
})
|
||||
@ -61,7 +58,7 @@ in
|
||||
};
|
||||
users.groups.goeland = { };
|
||||
|
||||
warnings = optionals (hasAttr "password" cfg.settings.email) [
|
||||
warnings = lib.optionals (lib.hasAttr "password" cfg.settings.email) [
|
||||
''
|
||||
It is not recommended to set the "services.goeland.settings.email.password"
|
||||
option as it will be in cleartext in the Nix store.
|
||||
@ -70,5 +67,5 @@ in
|
||||
];
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ sweenu ];
|
||||
meta.maintainers = with lib.maintainers; [ sweenu ];
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.listmonk;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
@ -11,7 +9,7 @@ let
|
||||
lib.replaceStrings [ "'" ] [ "''" ] (builtins.toJSON value)
|
||||
}' WHERE key = '${key}';";
|
||||
updateDatabaseConfigSQL = pkgs.writeText "update-database-config.sql"
|
||||
(concatStringsSep "\n" (mapAttrsToList setDatabaseOption
|
||||
(lib.concatStringsSep "\n" (lib.mapAttrsToList setDatabaseOption
|
||||
(if (cfg.database.settings != null) then
|
||||
cfg.database.settings
|
||||
else
|
||||
@ -27,53 +25,53 @@ let
|
||||
"${pkgs.postgresql}/bin/psql -d listmonk -f ${updateDatabaseConfigSQL}"}
|
||||
'';
|
||||
|
||||
databaseSettingsOpts = with types; {
|
||||
databaseSettingsOpts = with lib.types; {
|
||||
freeformType =
|
||||
oneOf [ (listOf str) (listOf (attrsOf anything)) str int bool ];
|
||||
|
||||
options = {
|
||||
"app.notify_emails" = mkOption {
|
||||
"app.notify_emails" = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = "Administrator emails for system notifications";
|
||||
};
|
||||
|
||||
"privacy.exportable" = mkOption {
|
||||
"privacy.exportable" = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [ "profile" "subscriptions" "campaign_views" "link_clicks" ];
|
||||
description =
|
||||
"List of fields which can be exported through an automatic export request";
|
||||
};
|
||||
|
||||
"privacy.domain_blocklist" = mkOption {
|
||||
"privacy.domain_blocklist" = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description =
|
||||
"E-mail addresses with these domains are disallowed from subscribing.";
|
||||
};
|
||||
|
||||
smtp = mkOption {
|
||||
smtp = lib.mkOption {
|
||||
type = listOf (submodule {
|
||||
freeformType = with types; attrsOf anything;
|
||||
freeformType = with lib.types; attrsOf anything;
|
||||
|
||||
options = {
|
||||
enabled = mkEnableOption "this SMTP server for listmonk";
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
enabled = lib.mkEnableOption "this SMTP server for listmonk";
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Hostname for the SMTP server";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "Port for the SMTP server";
|
||||
};
|
||||
max_conns = mkOption {
|
||||
type = types.int;
|
||||
max_conns = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description =
|
||||
"Maximum number of simultaneous connections, defaults to 1";
|
||||
default = 1;
|
||||
};
|
||||
tls_type = mkOption {
|
||||
type = types.enum [ "none" "STARTTLS" "TLS" ];
|
||||
tls_type = lib.mkOption {
|
||||
type = lib.types.enum [ "none" "STARTTLS" "TLS" ];
|
||||
description = "Type of TLS authentication with the SMTP server";
|
||||
};
|
||||
};
|
||||
@ -83,14 +81,14 @@ let
|
||||
};
|
||||
|
||||
# TODO: refine this type based on the smtp one.
|
||||
"bounce.mailboxes" = mkOption {
|
||||
"bounce.mailboxes" = lib.mkOption {
|
||||
type = listOf
|
||||
(submodule { freeformType = with types; listOf (attrsOf anything); });
|
||||
(submodule { freeformType = with lib.types; listOf (attrsOf anything); });
|
||||
default = [ ];
|
||||
description = "List of bounce mailboxes";
|
||||
};
|
||||
|
||||
messengers = mkOption {
|
||||
messengers = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description =
|
||||
@ -102,23 +100,23 @@ in {
|
||||
###### interface
|
||||
options = {
|
||||
services.listmonk = {
|
||||
enable = mkEnableOption "Listmonk, this module assumes a reverse proxy to be set";
|
||||
enable = lib.mkEnableOption "Listmonk, this module assumes a reverse proxy to be set";
|
||||
database = {
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
createLocally = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description =
|
||||
"Create the PostgreSQL database and database user locally.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr (submodule databaseSettingsOpts);
|
||||
type = with lib.types; nullOr (submodule databaseSettingsOpts);
|
||||
description =
|
||||
"Dynamic settings in the PostgreSQL database, set by a SQL script, see <https://github.com/knadh/listmonk/blob/master/schema.sql#L177-L230> for details.";
|
||||
};
|
||||
mutableSettings = mkOption {
|
||||
type = types.bool;
|
||||
mutableSettings = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Database settings will be reset to the value set in this module if this is not enabled.
|
||||
@ -126,16 +124,16 @@ in {
|
||||
'';
|
||||
};
|
||||
};
|
||||
package = mkPackageOption pkgs "listmonk" {};
|
||||
settings = mkOption {
|
||||
type = types.submodule { freeformType = tomlFormat.type; };
|
||||
package = lib.mkPackageOption pkgs "listmonk" {};
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule { freeformType = tomlFormat.type; };
|
||||
description = ''
|
||||
Static settings set in the config.toml, see <https://github.com/knadh/listmonk/blob/master/config.toml.sample> for details.
|
||||
You can set secrets using the secretFile option with environment variables following <https://listmonk.app/docs/configuration/#environment-variables>.
|
||||
'';
|
||||
};
|
||||
secretFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
secretFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description =
|
||||
"A file containing secrets as environment variables. See <https://listmonk.app/docs/configuration/#environment-variables> for details on supported values.";
|
||||
@ -144,24 +142,24 @@ in {
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Default parameters from https://github.com/knadh/listmonk/blob/master/config.toml.sample
|
||||
services.listmonk.settings."app".address = mkDefault "localhost:9000";
|
||||
services.listmonk.settings."db" = mkMerge [
|
||||
services.listmonk.settings."app".address = lib.mkDefault "localhost:9000";
|
||||
services.listmonk.settings."db" = lib.mkMerge [
|
||||
({
|
||||
max_open = mkDefault 25;
|
||||
max_idle = mkDefault 25;
|
||||
max_lifetime = mkDefault "300s";
|
||||
max_open = lib.mkDefault 25;
|
||||
max_idle = lib.mkDefault 25;
|
||||
max_lifetime = lib.mkDefault "300s";
|
||||
})
|
||||
(mkIf cfg.database.createLocally {
|
||||
host = mkDefault "/run/postgresql";
|
||||
port = mkDefault 5432;
|
||||
user = mkDefault "listmonk";
|
||||
database = mkDefault "listmonk";
|
||||
(lib.mkIf cfg.database.createLocally {
|
||||
host = lib.mkDefault "/run/postgresql";
|
||||
port = lib.mkDefault 5432;
|
||||
user = lib.mkDefault "listmonk";
|
||||
database = lib.mkDefault "listmonk";
|
||||
})
|
||||
];
|
||||
|
||||
services.postgresql = mkIf cfg.database.createLocally {
|
||||
services.postgresql = lib.mkIf cfg.database.createLocally {
|
||||
enable = true;
|
||||
|
||||
ensureUsers = [{
|
||||
@ -175,11 +173,11 @@ in {
|
||||
systemd.services.listmonk = {
|
||||
description = "Listmonk - newsletter and mailing list manager";
|
||||
after = [ "network.target" ]
|
||||
++ optional cfg.database.createLocally "postgresql.service";
|
||||
++ lib.optional cfg.database.createLocally "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
EnvironmentFile = mkIf (cfg.secretFile != null) [ cfg.secretFile ];
|
||||
EnvironmentFile = lib.mkIf (cfg.secretFile != null) [ cfg.secretFile ];
|
||||
ExecStartPre = [
|
||||
# StateDirectory cannot be used when DynamicUser = true is set this way.
|
||||
# Indeed, it will try to create all the folders and realize one of them already exist.
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
name = "maddy";
|
||||
@ -138,11 +135,11 @@ in {
|
||||
options = {
|
||||
services.maddy = {
|
||||
|
||||
enable = mkEnableOption "Maddy, a free an open source mail server";
|
||||
enable = lib.mkEnableOption "Maddy, a free an open source mail server";
|
||||
|
||||
user = mkOption {
|
||||
user = lib.mkOption {
|
||||
default = "maddy";
|
||||
type = with types; uniq str;
|
||||
type = with lib.types; uniq str;
|
||||
description = ''
|
||||
User account under which maddy runs.
|
||||
|
||||
@ -154,9 +151,9 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
group = lib.mkOption {
|
||||
default = "maddy";
|
||||
type = with types; uniq str;
|
||||
type = with lib.types; uniq str;
|
||||
description = ''
|
||||
Group account under which maddy runs.
|
||||
|
||||
@ -168,26 +165,26 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
hostname = lib.mkOption {
|
||||
default = "localhost";
|
||||
type = with types; uniq str;
|
||||
type = with lib.types; uniq str;
|
||||
example = ''example.com'';
|
||||
description = ''
|
||||
Hostname to use. It should be FQDN.
|
||||
'';
|
||||
};
|
||||
|
||||
primaryDomain = mkOption {
|
||||
primaryDomain = lib.mkOption {
|
||||
default = "localhost";
|
||||
type = with types; uniq str;
|
||||
type = with lib.types; uniq str;
|
||||
example = ''mail.example.com'';
|
||||
description = ''
|
||||
Primary MX domain to use. It should be FQDN.
|
||||
'';
|
||||
};
|
||||
|
||||
localDomains = mkOption {
|
||||
type = with types; listOf str;
|
||||
localDomains = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = ["$(primary_domain)"];
|
||||
example = [
|
||||
"$(primary_domain)"
|
||||
@ -199,8 +196,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = with types; nullOr lines;
|
||||
config = lib.mkOption {
|
||||
type = with lib.types; nullOr lines;
|
||||
default = defaultConfig;
|
||||
description = ''
|
||||
Server configuration, see
|
||||
@ -215,8 +212,8 @@ in {
|
||||
};
|
||||
|
||||
tls = {
|
||||
loader = mkOption {
|
||||
type = with types; nullOr (enum [ "off" "file" "acme" ]);
|
||||
loader = lib.mkOption {
|
||||
type = with lib.types; nullOr (enum [ "off" "file" "acme" ]);
|
||||
default = "off";
|
||||
description = ''
|
||||
TLS certificates are obtained by modules called "certificate
|
||||
@ -237,18 +234,18 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
certificates = mkOption {
|
||||
type = with types; listOf (submodule {
|
||||
certificates = lib.mkOption {
|
||||
type = with lib.types; listOf (submodule {
|
||||
options = {
|
||||
keyPath = mkOption {
|
||||
type = types.path;
|
||||
keyPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = "/etc/ssl/mx1.example.org.key";
|
||||
description = ''
|
||||
Path to the private key used for TLS.
|
||||
'';
|
||||
};
|
||||
certPath = mkOption {
|
||||
type = types.path;
|
||||
certPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = "/etc/ssl/mx1.example.org.crt";
|
||||
description = ''
|
||||
Path to the certificate used for TLS.
|
||||
@ -269,8 +266,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; nullOr lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = with lib.types; nullOr lines;
|
||||
description = ''
|
||||
Arguments for the specified certificate loader.
|
||||
|
||||
@ -284,16 +281,16 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open the configured incoming and outgoing mail server ports.
|
||||
'';
|
||||
};
|
||||
|
||||
ensureAccounts = mkOption {
|
||||
type = with types; listOf str;
|
||||
ensureAccounts = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of IMAP accounts which get automatically created. Note that for
|
||||
@ -307,7 +304,7 @@ in {
|
||||
];
|
||||
};
|
||||
|
||||
ensureCredentials = mkOption {
|
||||
ensureCredentials = lib.mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
List of user accounts which get automatically created if they don't
|
||||
@ -319,10 +316,10 @@ in {
|
||||
"user1@localhost".passwordFile = /secrets/user1-localhost;
|
||||
"user2@localhost".passwordFile = /secrets/user2-localhost;
|
||||
};
|
||||
type = types.attrsOf (types.submodule {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = "/path/to/file";
|
||||
default = null;
|
||||
description = ''
|
||||
@ -335,7 +332,7 @@ in {
|
||||
};
|
||||
|
||||
secrets = lib.mkOption {
|
||||
type = with types; listOf path;
|
||||
type = with lib.types; listOf path;
|
||||
description = ''
|
||||
A list of files containing the various secrets. Should be in the format
|
||||
expected by systemd's `EnvironmentFile` directory. Secrets can be
|
||||
@ -347,7 +344,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
assertions = [
|
||||
{
|
||||
@ -387,17 +384,17 @@ in {
|
||||
};
|
||||
maddy-ensure-accounts = {
|
||||
script = ''
|
||||
${optionalString (cfg.ensureAccounts != []) ''
|
||||
${concatMapStrings (account: ''
|
||||
${lib.optionalString (cfg.ensureAccounts != []) ''
|
||||
${lib.concatMapStrings (account: ''
|
||||
if ! ${pkgs.maddy}/bin/maddyctl imap-acct list | grep "${account}"; then
|
||||
${pkgs.maddy}/bin/maddyctl imap-acct create ${account}
|
||||
fi
|
||||
'') cfg.ensureAccounts}
|
||||
''}
|
||||
${optionalString (cfg.ensureCredentials != {}) ''
|
||||
${concatStringsSep "\n" (mapAttrsToList (name: cfg: ''
|
||||
${lib.optionalString (cfg.ensureCredentials != {}) ''
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: cfg: ''
|
||||
if ! ${pkgs.maddy}/bin/maddyctl creds list | grep "${name}"; then
|
||||
${pkgs.maddy}/bin/maddyctl creds create --password $(cat ${escapeShellArg cfg.passwordFile}) ${name}
|
||||
${pkgs.maddy}/bin/maddyctl creds create --password $(cat ${lib.escapeShellArg cfg.passwordFile}) ${name}
|
||||
fi
|
||||
'') cfg.ensureCredentials)}
|
||||
''}
|
||||
@ -422,9 +419,9 @@ in {
|
||||
hostname ${cfg.hostname}
|
||||
|
||||
${if (cfg.tls.loader == "file") then ''
|
||||
tls file ${concatStringsSep " " (
|
||||
tls file ${lib.concatStringsSep " " (
|
||||
map (x: x.certPath + " " + x.keyPath
|
||||
) cfg.tls.certificates)} ${optionalString (cfg.tls.extraConfig != "") ''
|
||||
) cfg.tls.certificates)} ${lib.optionalString (cfg.tls.extraConfig != "") ''
|
||||
{ ${cfg.tls.extraConfig} }
|
||||
''}
|
||||
'' else if (cfg.tls.loader == "acme") then ''
|
||||
@ -441,7 +438,7 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
users.users = optionalAttrs (cfg.user == name) {
|
||||
users.users = lib.optionalAttrs (cfg.user == name) {
|
||||
${name} = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
@ -449,11 +446,11 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == name) {
|
||||
users.groups = lib.optionalAttrs (cfg.group == name) {
|
||||
${cfg.group} = { };
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 25 143 587 ];
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, options, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
@ -10,8 +7,8 @@ with lib;
|
||||
|
||||
services.mail = {
|
||||
|
||||
sendmailSetuidWrapper = mkOption {
|
||||
type = types.nullOr options.security.wrappers.type.nestedTypes.elemType;
|
||||
sendmailSetuidWrapper = lib.mkOption {
|
||||
type = lib.types.nullOr options.security.wrappers.type.nestedTypes.elemType;
|
||||
default = null;
|
||||
internal = true;
|
||||
description = ''
|
||||
@ -25,7 +22,7 @@ with lib;
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf (config.services.mail.sendmailSetuidWrapper != null) {
|
||||
config = lib.mkIf (config.services.mail.sendmailSetuidWrapper != null) {
|
||||
|
||||
security.wrappers.sendmail = config.services.mail.sendmailSetuidWrapper;
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.mailhog;
|
||||
|
||||
@ -21,40 +18,40 @@ in
|
||||
###### interface
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "mailhog" "user" ] "")
|
||||
(lib.mkRemovedOptionModule [ "services" "mailhog" "user" ] "")
|
||||
];
|
||||
|
||||
options = {
|
||||
|
||||
services.mailhog = {
|
||||
enable = mkEnableOption "MailHog, web and API based SMTP testing";
|
||||
enable = lib.mkEnableOption "MailHog, web and API based SMTP testing";
|
||||
|
||||
storage = mkOption {
|
||||
type = types.enum [ "maildir" "memory" ];
|
||||
storage = lib.mkOption {
|
||||
type = lib.types.enum [ "maildir" "memory" ];
|
||||
default = "memory";
|
||||
description = "Store mails on disk or in memory.";
|
||||
};
|
||||
|
||||
apiPort = mkOption {
|
||||
type = types.port;
|
||||
apiPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8025;
|
||||
description = "Port on which the API endpoint will listen.";
|
||||
};
|
||||
|
||||
smtpPort = mkOption {
|
||||
type = types.port;
|
||||
smtpPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 1025;
|
||||
description = "Port on which the SMTP endpoint will listen.";
|
||||
};
|
||||
|
||||
uiPort = mkOption {
|
||||
type = types.port;
|
||||
uiPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8025;
|
||||
description = "Port on which the HTTP UI will listen.";
|
||||
};
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "List of additional arguments to pass to the MailHog process.";
|
||||
};
|
||||
@ -64,7 +61,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.services.mailhog = {
|
||||
description = "MailHog - Web and API based SMTP testing";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
concatMapLines = f: l: lib.concatStringsSep "\n" (map f l);
|
||||
@ -53,38 +50,38 @@ in
|
||||
|
||||
services.mlmmj = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable mlmmj";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "mlmmj";
|
||||
description = "mailinglist local user";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "mlmmj";
|
||||
description = "mailinglist local group";
|
||||
};
|
||||
|
||||
listDomain = mkOption {
|
||||
type = types.str;
|
||||
listDomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = "Set the mailing list domain";
|
||||
};
|
||||
|
||||
mailLists = mkOption {
|
||||
type = types.listOf types.str;
|
||||
mailLists = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "The collection of hosted maillists";
|
||||
};
|
||||
|
||||
maintInterval = mkOption {
|
||||
type = types.str;
|
||||
maintInterval = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "20min";
|
||||
description = ''
|
||||
Time interval between mlmmj-maintd runs, see
|
||||
@ -98,7 +95,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
description = "mlmmj user";
|
||||
|
@ -1,42 +1,39 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
services.nullmailer = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable nullmailer daemon.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nullmailer";
|
||||
description = ''
|
||||
User to use to run nullmailer-send.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nullmailer";
|
||||
description = ''
|
||||
Group to use to run nullmailer-send.
|
||||
'';
|
||||
};
|
||||
|
||||
setSendmail = mkOption {
|
||||
type = types.bool;
|
||||
setSendmail = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to set the system sendmail to nullmailer's.";
|
||||
};
|
||||
|
||||
remotesFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
remotesFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the `remotes` control file. This file contains a
|
||||
@ -48,8 +45,8 @@ with lib;
|
||||
};
|
||||
|
||||
config = {
|
||||
adminaddr = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
adminaddr = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set, all recipients to users at either "localhost" (the literal string)
|
||||
@ -61,16 +58,16 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
allmailfrom = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
allmailfrom = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set, content will override the envelope sender on all messages.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultdomain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
defaultdomain = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The content of this attribute is appended to any host name that
|
||||
@ -80,8 +77,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
defaulthost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
defaulthost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The content of this attribute is appended to any address that
|
||||
@ -90,8 +87,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
doublebounceto = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
doublebounceto = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If the original sender was empty (the original message was a
|
||||
@ -100,8 +97,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
helohost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
helohost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Sets the environment variable $HELOHOST which is used by the
|
||||
@ -110,8 +107,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
idhost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
idhost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The content of this attribute is used when building the message-id
|
||||
@ -119,8 +116,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
maxpause = mkOption {
|
||||
type = with types; nullOr (oneOf [ str int ]);
|
||||
maxpause = lib.mkOption {
|
||||
type = with lib.types; nullOr (oneOf [ str int ]);
|
||||
default = null;
|
||||
description = ''
|
||||
The maximum time to pause between successive queue runs, in seconds.
|
||||
@ -128,8 +125,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
me = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
me = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The fully-qualifiled host name of the computer running nullmailer.
|
||||
@ -137,8 +134,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
pausetime = mkOption {
|
||||
type = with types; nullOr (oneOf [ str int ]);
|
||||
pausetime = lib.mkOption {
|
||||
type = with lib.types; nullOr (oneOf [ str int ]);
|
||||
default = null;
|
||||
description = ''
|
||||
The minimum time to pause between successive queue runs when there
|
||||
@ -150,8 +147,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
remotes = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
remotes = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
A list of remote servers to which to send each message. Each line
|
||||
@ -167,8 +164,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
sendtimeout = mkOption {
|
||||
type = with types; nullOr (oneOf [ str int ]);
|
||||
sendtimeout = lib.mkOption {
|
||||
type = with lib.types; nullOr (oneOf [ str int ]);
|
||||
default = null;
|
||||
description = ''
|
||||
The time to wait for a remote module listed above to complete sending
|
||||
@ -183,7 +180,7 @@ with lib;
|
||||
|
||||
config = let
|
||||
cfg = config.services.nullmailer;
|
||||
in mkIf cfg.enable {
|
||||
in lib.mkIf cfg.enable {
|
||||
|
||||
assertions = [
|
||||
{ assertion = cfg.config.remotes == null || cfg.remotesFile == null;
|
||||
@ -194,10 +191,10 @@ with lib;
|
||||
environment = {
|
||||
systemPackages = [ pkgs.nullmailer ];
|
||||
etc = let
|
||||
validAttrs = lib.mapAttrs (_: toString) (filterAttrs (_: value: value != null) cfg.config);
|
||||
validAttrs = lib.mapAttrs (_: toString) (lib.filterAttrs (_: value: value != null) cfg.config);
|
||||
in
|
||||
(foldl' (as: name: as // { "nullmailer/${name}".text = validAttrs.${name}; }) {} (attrNames validAttrs))
|
||||
// optionalAttrs (cfg.remotesFile != null) { "nullmailer/remotes".source = cfg.remotesFile; };
|
||||
(lib.foldl' (as: name: as // { "nullmailer/${name}".text = validAttrs.${name}; }) {} (lib.attrNames validAttrs))
|
||||
// lib.optionalAttrs (cfg.remotesFile != null) { "nullmailer/remotes".source = cfg.remotesFile; };
|
||||
};
|
||||
|
||||
users = {
|
||||
@ -234,7 +231,7 @@ with lib;
|
||||
};
|
||||
};
|
||||
|
||||
services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail {
|
||||
services.mail.sendmailSetuidWrapper = lib.mkIf cfg.setSendmail {
|
||||
program = "sendmail";
|
||||
source = "${pkgs.nullmailer}/bin/sendmail";
|
||||
owner = cfg.user;
|
||||
|
@ -1,16 +1,13 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.offlineimap;
|
||||
in {
|
||||
|
||||
options.services.offlineimap = {
|
||||
enable = mkEnableOption "OfflineIMAP, a software to dispose your mailbox(es) as a local Maildir(s)";
|
||||
enable = lib.mkEnableOption "OfflineIMAP, a software to dispose your mailbox(es) as a local Maildir(s)";
|
||||
|
||||
install = mkOption {
|
||||
type = types.bool;
|
||||
install = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to install a user service for Offlineimap. Once
|
||||
@ -22,28 +19,28 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "offlineimap" { };
|
||||
package = lib.mkPackageOption pkgs "offlineimap" { };
|
||||
|
||||
path = mkOption {
|
||||
type = types.listOf types.path;
|
||||
path = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
example = literalExpression "[ pkgs.pass pkgs.bash pkgs.notmuch ]";
|
||||
example = lib.literalExpression "[ pkgs.pass pkgs.bash pkgs.notmuch ]";
|
||||
description = "List of derivations to put in Offlineimap's path.";
|
||||
};
|
||||
|
||||
onCalendar = mkOption {
|
||||
type = types.str;
|
||||
onCalendar = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "*:0/3"; # every 3 minutes
|
||||
description = "How often is offlineimap started. Default is '*:0/3' meaning every 3 minutes. See systemd.time(7) for more information about the format.";
|
||||
};
|
||||
|
||||
timeoutStartSec = mkOption {
|
||||
type = types.str;
|
||||
timeoutStartSec = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "120sec"; # Kill if still alive after 2 minutes
|
||||
description = "How long waiting for offlineimap before killing it. Default is '120sec' meaning every 2 minutes. See systemd.time(7) for more information about the format.";
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable || cfg.install) {
|
||||
config = lib.mkIf (cfg.enable || cfg.install) {
|
||||
systemd.user.services.offlineimap = {
|
||||
description = "Offlineimap: a software to dispose your mailbox(es) as a local Maildir(s)";
|
||||
serviceConfig = {
|
||||
@ -62,6 +59,6 @@ in {
|
||||
# start immediately after computer is started:
|
||||
Persistent = "true";
|
||||
};
|
||||
} // optionalAttrs cfg.enable { wantedBy = [ "default.target" ]; };
|
||||
} // lib.optionalAttrs cfg.enable { wantedBy = [ "default.target" ]; };
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.opendkim;
|
||||
@ -15,11 +12,11 @@ let
|
||||
"-d" cfg.domains
|
||||
"-k" keyFile
|
||||
"-s" cfg.selector
|
||||
] ++ optionals (cfg.configFile != null) [ "-x" cfg.configFile ];
|
||||
] ++ lib.optionals (cfg.configFile != null) [ "-x" cfg.configFile ];
|
||||
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "opendkim" "keyFile" ] [ "services" "opendkim" "keyPath" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "opendkim" "keyFile" ] [ "services" "opendkim" "keyPath" ])
|
||||
];
|
||||
|
||||
###### interface
|
||||
@ -28,34 +25,34 @@ in {
|
||||
|
||||
services.opendkim = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the OpenDKIM sender authentication system.";
|
||||
};
|
||||
|
||||
socket = mkOption {
|
||||
type = types.str;
|
||||
socket = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultSock;
|
||||
description = "Socket which is used for communication with OpenDKIM.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "opendkim";
|
||||
description = "User for the daemon.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "opendkim";
|
||||
description = "Group for the daemon.";
|
||||
};
|
||||
|
||||
domains = mkOption {
|
||||
type = types.str;
|
||||
domains = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "csl:${config.networking.hostName}";
|
||||
defaultText = literalExpression ''"csl:''${config.networking.hostName}"'';
|
||||
defaultText = lib.literalExpression ''"csl:''${config.networking.hostName}"'';
|
||||
example = "csl:example.com,mydomain.net";
|
||||
description = ''
|
||||
Local domains set (see `opendkim(8)` for more information on datasets).
|
||||
@ -63,8 +60,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
keyPath = mkOption {
|
||||
type = types.path;
|
||||
keyPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
The path that opendkim should put its generated private keys into.
|
||||
The DNS settings will be found in this directory with the name selector.txt.
|
||||
@ -72,13 +69,13 @@ in {
|
||||
default = "/var/lib/opendkim/keys";
|
||||
};
|
||||
|
||||
selector = mkOption {
|
||||
type = types.str;
|
||||
selector = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Selector to use when signing.";
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "Additional opendkim configuration.";
|
||||
};
|
||||
@ -90,16 +87,16 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "opendkim") {
|
||||
users.users = lib.optionalAttrs (cfg.user == "opendkim") {
|
||||
opendkim = {
|
||||
group = cfg.group;
|
||||
uid = config.ids.uids.opendkim;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == "opendkim") {
|
||||
users.groups = lib.optionalAttrs (cfg.group == "opendkim") {
|
||||
opendkim.gid = config.ids.gids.opendkim;
|
||||
};
|
||||
|
||||
@ -126,10 +123,10 @@ in {
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.opendkim}/bin/opendkim ${escapeShellArgs args}";
|
||||
ExecStart = "${pkgs.opendkim}/bin/opendkim ${lib.escapeShellArgs args}";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim";
|
||||
RuntimeDirectory = lib.optional (cfg.socket == defaultSock) "opendkim";
|
||||
StateDirectory = "opendkim";
|
||||
StateDirectoryMode = "0700";
|
||||
ReadWritePaths = [ cfg.keyPath ];
|
||||
|
@ -1,12 +1,9 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.opensmtpd;
|
||||
conf = pkgs.writeText "smtpd.conf" cfg.serverConfiguration;
|
||||
args = concatStringsSep " " cfg.extraServerArgs;
|
||||
args = lib.concatStringsSep " " cfg.extraServerArgs;
|
||||
|
||||
sendmail = pkgs.runCommand "opensmtpd-sendmail" { preferLocalBuild = true; } ''
|
||||
mkdir -p $out/bin
|
||||
@ -18,29 +15,29 @@ in {
|
||||
###### interface
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "opensmtpd" "addSendmailToSystemPath" ] [ "services" "opensmtpd" "setSendmail" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "opensmtpd" "addSendmailToSystemPath" ] [ "services" "opensmtpd" "setSendmail" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
|
||||
services.opensmtpd = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the OpenSMTPD server.";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "opensmtpd" { };
|
||||
package = lib.mkPackageOption pkgs "opensmtpd" { };
|
||||
|
||||
setSendmail = mkOption {
|
||||
type = types.bool;
|
||||
setSendmail = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to set the system sendmail to OpenSMTPD's.";
|
||||
};
|
||||
|
||||
extraServerArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraServerArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
example = [ "-v" "-P mta" ];
|
||||
description = ''
|
||||
@ -49,8 +46,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
serverConfiguration = mkOption {
|
||||
type = types.lines;
|
||||
serverConfiguration = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
example = ''
|
||||
listen on lo
|
||||
accept for any deliver to lmtp localhost:24
|
||||
@ -61,8 +58,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
procPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
procPackages = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [];
|
||||
description = ''
|
||||
Packages to search for filters, tables, queues, and schedulers.
|
||||
@ -78,7 +75,7 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable rec {
|
||||
config = lib.mkIf cfg.enable rec {
|
||||
users.groups = {
|
||||
smtpd.gid = config.ids.gids.smtpd;
|
||||
smtpq.gid = config.ids.gids.smtpq;
|
||||
@ -105,7 +102,7 @@ in {
|
||||
source = "${cfg.package}/bin/smtpctl";
|
||||
};
|
||||
|
||||
services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail
|
||||
services.mail.sendmailSetuidWrapper = lib.mkIf cfg.setSendmail
|
||||
(security.wrappers.smtpctl // { program = "sendmail"; });
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
@ -9,25 +6,25 @@ with lib;
|
||||
options = {
|
||||
|
||||
services.pfix-srsd = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = "Whether to run the postfix sender rewriting scheme daemon.";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
domain = lib.mkOption {
|
||||
description = "The domain for which to enable srs";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
example = "example.com";
|
||||
};
|
||||
|
||||
secretsFile = mkOption {
|
||||
secretsFile = lib.mkOption {
|
||||
description = ''
|
||||
The secret data used to encode the SRS address.
|
||||
to generate, use a command like:
|
||||
`for n in $(seq 5); do dd if=/dev/urandom count=1 bs=1024 status=none | sha256sum | sed 's/ -$//' | sed 's/^/ /'; done`
|
||||
'';
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/pfix-srsd/secrets";
|
||||
};
|
||||
};
|
||||
@ -35,7 +32,7 @@ with lib;
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.pfix-srsd.enable {
|
||||
config = lib.mkIf config.services.pfix-srsd.enable {
|
||||
environment = {
|
||||
systemPackages = [ pkgs.pfixtools ];
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.postfixadmin;
|
||||
fpm = config.services.phpfpm.pools.postfixadmin;
|
||||
@ -10,8 +7,8 @@ let
|
||||
in
|
||||
{
|
||||
options.services.postfixadmin = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable postfixadmin.
|
||||
@ -22,14 +19,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
hostName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "postfixadmin.example.com";
|
||||
description = "Hostname to use for the nginx vhost";
|
||||
};
|
||||
|
||||
adminEmail = mkOption {
|
||||
type = types.str;
|
||||
adminEmail = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "postmaster@example.com";
|
||||
description = ''
|
||||
Defines the Site Admin's email address.
|
||||
@ -38,8 +35,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
setupPasswordFile = mkOption {
|
||||
type = types.path;
|
||||
setupPasswordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
Password file for the admin.
|
||||
Generate with `php -r "echo password_hash('some password here', PASSWORD_DEFAULT);"`
|
||||
@ -47,16 +44,16 @@ in
|
||||
};
|
||||
|
||||
database = {
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "postfixadmin";
|
||||
description = ''
|
||||
Username for the postgresql connection.
|
||||
If `database.host` is set to `localhost`, a unix user and group of the same name will be created as well.
|
||||
'';
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Host of the postgresql server. If this is not set to
|
||||
@ -65,25 +62,25 @@ in
|
||||
permissions.
|
||||
'';
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Password file for the postgresql connection. Must be readable by user `nginx`.";
|
||||
};
|
||||
dbname = mkOption {
|
||||
type = types.str;
|
||||
dbname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "postfixadmin";
|
||||
description = "Name of the postgresql database";
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = "Extra configuration for the postfixadmin instance, see postfixadmin's config.inc.php for available options.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc."postfixadmin/config.local.php".text = ''
|
||||
<?php
|
||||
|
||||
@ -91,7 +88,7 @@ in
|
||||
|
||||
$CONF['database_type'] = 'pgsql';
|
||||
$CONF['database_host'] = ${if localDB then "null" else "'${cfg.database.host}'"};
|
||||
${optionalString localDB "$CONF['database_user'] = '${cfg.database.username}';"}
|
||||
${lib.optionalString localDB "$CONF['database_user'] = '${cfg.database.username}';"}
|
||||
$CONF['database_password'] = ${if localDB then "'dummy'" else "file_get_contents('${cfg.database.passwordFile}')"};
|
||||
$CONF['database_name'] = '${cfg.database.dbname}';
|
||||
$CONF['configured'] = true;
|
||||
@ -109,8 +106,8 @@ in
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.hostName} = {
|
||||
forceSSL = mkDefault true;
|
||||
enableACME = mkDefault true;
|
||||
forceSSL = lib.mkDefault true;
|
||||
enableACME = lib.mkDefault true;
|
||||
locations."/" = {
|
||||
root = "${pkgs.postfixadmin}/public";
|
||||
index = "index.php";
|
||||
@ -127,7 +124,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
services.postgresql = mkIf localDB {
|
||||
services.postgresql = lib.mkIf localDB {
|
||||
enable = true;
|
||||
ensureUsers = [ {
|
||||
name = cfg.database.username;
|
||||
@ -136,7 +133,7 @@ in
|
||||
# The postgresql module doesn't currently support concepts like
|
||||
# objects owners and extensions; for now we tack on what's needed
|
||||
# here.
|
||||
systemd.services.postfixadmin-postgres = let pgsql = config.services.postgresql; in mkIf localDB {
|
||||
systemd.services.postfixadmin-postgres = let pgsql = config.services.postgresql; in lib.mkIf localDB {
|
||||
after = [ "postgresql.service" ];
|
||||
bindsTo = [ "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
@ -172,12 +169,12 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${user} = mkIf localDB {
|
||||
users.users.${user} = lib.mkIf localDB {
|
||||
group = user;
|
||||
isSystemUser = true;
|
||||
createHome = false;
|
||||
};
|
||||
users.groups.${user} = mkIf localDB {};
|
||||
users.groups.${user} = lib.mkIf localDB {};
|
||||
|
||||
services.phpfpm.pools.postfixadmin = {
|
||||
user = user;
|
||||
@ -186,7 +183,7 @@ in
|
||||
error_log = 'stderr'
|
||||
log_errors = on
|
||||
'';
|
||||
settings = mapAttrs (name: mkDefault) {
|
||||
settings = lib.mapAttrs (name: lib.mkDefault) {
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
"listen.mode" = "0660";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.postsrsd;
|
||||
@ -14,67 +11,67 @@ in {
|
||||
|
||||
services.postsrsd = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the postsrsd SRS server for Postfix.";
|
||||
};
|
||||
|
||||
secretsFile = mkOption {
|
||||
type = types.path;
|
||||
secretsFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/postsrsd/postsrsd.secret";
|
||||
description = "Secret keys used for signing and verification";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Domain name for rewrite";
|
||||
};
|
||||
|
||||
separator = mkOption {
|
||||
type = types.enum ["-" "=" "+"];
|
||||
separator = lib.mkOption {
|
||||
type = lib.types.enum ["-" "=" "+"];
|
||||
default = "=";
|
||||
description = "First separator character in generated addresses";
|
||||
};
|
||||
|
||||
# bindAddress = mkOption { # uncomment once 1.5 is released
|
||||
# type = types.str;
|
||||
# bindAddress = lib.mkOption { # uncomment once 1.5 is released
|
||||
# type = lib.types.str;
|
||||
# default = "127.0.0.1";
|
||||
# description = "Socket listen address";
|
||||
# };
|
||||
|
||||
forwardPort = mkOption {
|
||||
type = types.int;
|
||||
forwardPort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10001;
|
||||
description = "Port for the forward SRS lookup";
|
||||
};
|
||||
|
||||
reversePort = mkOption {
|
||||
type = types.int;
|
||||
reversePort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10002;
|
||||
description = "Port for the reverse SRS lookup";
|
||||
};
|
||||
|
||||
timeout = mkOption {
|
||||
type = types.int;
|
||||
timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 1800;
|
||||
description = "Timeout for idle client connections in seconds";
|
||||
};
|
||||
|
||||
excludeDomains = mkOption {
|
||||
type = types.listOf types.str;
|
||||
excludeDomains = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Origin domains to exclude from rewriting in addition to primary domain";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "postsrsd";
|
||||
description = "User for the daemon";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "postsrsd";
|
||||
description = "Group for the daemon";
|
||||
};
|
||||
@ -86,18 +83,18 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
services.postsrsd.domain = mkDefault config.networking.hostName;
|
||||
services.postsrsd.domain = lib.mkDefault config.networking.hostName;
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "postsrsd") {
|
||||
users.users = lib.optionalAttrs (cfg.user == "postsrsd") {
|
||||
postsrsd = {
|
||||
group = cfg.group;
|
||||
uid = config.ids.uids.postsrsd;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == "postsrsd") {
|
||||
users.groups = lib.optionalAttrs (cfg.group == "postsrsd") {
|
||||
postsrsd.gid = config.ids.gids.postsrsd;
|
||||
};
|
||||
|
||||
@ -110,7 +107,7 @@ in {
|
||||
path = [ pkgs.coreutils ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -a${cfg.separator} -f${toString cfg.forwardPort} -r${toString cfg.reversePort} -t${toString cfg.timeout} "-X${concatStringsSep "," cfg.excludeDomains}"'';
|
||||
ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -a${cfg.separator} -f${toString cfg.forwardPort} -r${toString cfg.reversePort} -t${toString cfg.timeout} "-X${lib.concatStringsSep "," cfg.excludeDomains}"'';
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
PermissionsStartOnly = true;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.roundcube;
|
||||
fpm = config.services.phpfpm.pools.roundcube;
|
||||
@ -11,8 +8,8 @@ let
|
||||
in
|
||||
{
|
||||
options.services.roundcube = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable roundcube.
|
||||
@ -23,27 +20,27 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
hostName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "webmail.example.com";
|
||||
description = "Hostname to use for the nginx vhost";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "roundcube" {
|
||||
package = lib.mkPackageOption pkgs "roundcube" {
|
||||
example = "roundcube.withPlugins (plugins: [ plugins.persistent_login ])";
|
||||
};
|
||||
|
||||
database = {
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roundcube";
|
||||
description = ''
|
||||
Username for the postgresql connection.
|
||||
If `database.host` is set to `localhost`, a unix user and group of the same name will be created as well.
|
||||
'';
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Host of the postgresql server. If this is not set to
|
||||
@ -52,13 +49,13 @@ in
|
||||
permissions.
|
||||
'';
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
password = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Password for the postgresql connection. Do not use: the password will be stored world readable in the store; use `passwordFile` instead.";
|
||||
default = "";
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.str;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Password file for the postgresql connection.
|
||||
Must be formatted according to PostgreSQL .pgpass standard (see https://www.postgresql.org/docs/current/libpq-pgpass.html)
|
||||
@ -66,32 +63,32 @@ in
|
||||
Ignored if `database.host` is set to `localhost`, as peer authentication will be used.
|
||||
'';
|
||||
};
|
||||
dbname = mkOption {
|
||||
type = types.str;
|
||||
dbname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roundcube";
|
||||
description = "Name of the postgresql database";
|
||||
};
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.str;
|
||||
plugins = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of roundcube plugins to enable. Currently, only those directly shipped with Roundcube are supported.
|
||||
'';
|
||||
};
|
||||
|
||||
dicts = mkOption {
|
||||
type = types.listOf types.package;
|
||||
dicts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [];
|
||||
example = literalExpression "with pkgs.aspellDicts; [ en fr de ]";
|
||||
example = lib.literalExpression "with pkgs.aspellDicts; [ en fr de ]";
|
||||
description = ''
|
||||
List of aspell dictionaries for spell checking. If empty, spell checking is disabled.
|
||||
'';
|
||||
};
|
||||
|
||||
maxAttachmentSize = mkOption {
|
||||
type = types.int;
|
||||
maxAttachmentSize = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 18;
|
||||
apply = configuredMaxAttachmentSize: "${toString (configuredMaxAttachmentSize * 1.37)}M";
|
||||
description = ''
|
||||
@ -112,16 +109,16 @@ in
|
||||
description = "Configure nginx as a reverse proxy for roundcube.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = "Extra configuration for roundcube webmail instance";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# backward compatibility: if password is set but not passwordFile, make one.
|
||||
services.roundcube.database.passwordFile = mkIf (!localDB && cfg.database.password != "") (mkDefault ("${pkgs.writeText "roundcube-password" cfg.database.password}"));
|
||||
services.roundcube.database.passwordFile = lib.mkIf (!localDB && cfg.database.password != "") (lib.mkDefault ("${pkgs.writeText "roundcube-password" cfg.database.password}"));
|
||||
warnings = lib.optional (!localDB && cfg.database.password != "") "services.roundcube.database.password is deprecated and insecure; use services.roundcube.database.passwordFile instead";
|
||||
|
||||
environment.etc."roundcube/config.inc.php".text = ''
|
||||
@ -139,7 +136,7 @@ in
|
||||
$config['db_dsnw'] = 'pgsql://${cfg.database.username}${lib.optionalString (!localDB) ":' . $password . '"}@${if localDB then "unix(/run/postgresql)" else cfg.database.host}/${cfg.database.dbname}';
|
||||
$config['log_driver'] = 'syslog';
|
||||
$config['max_message_size'] = '${cfg.maxAttachmentSize}';
|
||||
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
||||
$config['plugins'] = [${lib.concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
||||
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
|
||||
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
|
||||
# Roundcube uses PHP-FPM which has `PrivateTmp = true;`
|
||||
@ -156,8 +153,8 @@ in
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
${cfg.hostName} = {
|
||||
forceSSL = mkDefault true;
|
||||
enableACME = mkDefault true;
|
||||
forceSSL = lib.mkDefault true;
|
||||
enableACME = lib.mkDefault true;
|
||||
root = cfg.package;
|
||||
locations."/" = {
|
||||
index = "index.php";
|
||||
@ -201,7 +198,7 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
services.postgresql = mkIf localDB {
|
||||
services.postgresql = lib.mkIf localDB {
|
||||
enable = true;
|
||||
ensureDatabases = [ cfg.database.dbname ];
|
||||
ensureUsers = [ {
|
||||
@ -210,12 +207,12 @@ in
|
||||
} ];
|
||||
};
|
||||
|
||||
users.users.${user} = mkIf localDB {
|
||||
users.users.${user} = lib.mkIf localDB {
|
||||
group = user;
|
||||
isSystemUser = true;
|
||||
createHome = false;
|
||||
};
|
||||
users.groups.${user} = mkIf localDB {};
|
||||
users.groups.${user} = lib.mkIf localDB {};
|
||||
|
||||
services.phpfpm.pools.roundcube = {
|
||||
user = if localDB then user else "nginx";
|
||||
@ -225,7 +222,7 @@ in
|
||||
post_max_size = ${cfg.maxAttachmentSize}
|
||||
upload_max_filesize = ${cfg.maxAttachmentSize}
|
||||
'';
|
||||
settings = mapAttrs (name: mkDefault) {
|
||||
settings = lib.mapAttrs (name: lib.mkDefault) {
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
"listen.mode" = "0660";
|
||||
@ -247,8 +244,8 @@ in
|
||||
config.environment.etc."roundcube/config.inc.php".source
|
||||
];
|
||||
|
||||
systemd.services.roundcube-setup = mkMerge [
|
||||
(mkIf (cfg.database.host == "localhost") {
|
||||
systemd.services.roundcube-setup = lib.mkMerge [
|
||||
(lib.mkIf (cfg.database.host == "localhost") {
|
||||
requires = [ "postgresql.service" ];
|
||||
after = [ "postgresql.service" ];
|
||||
})
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.spamassassin;
|
||||
spamassassin-local-cf = pkgs.writeText "local.cf" cfg.config;
|
||||
@ -12,16 +9,16 @@ in
|
||||
options = {
|
||||
|
||||
services.spamassassin = {
|
||||
enable = mkEnableOption "the SpamAssassin daemon";
|
||||
enable = lib.mkEnableOption "the SpamAssassin daemon";
|
||||
|
||||
debug = mkOption {
|
||||
type = types.bool;
|
||||
debug = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to run the SpamAssassin daemon in debug mode";
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
config = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
The SpamAssassin local.cf config
|
||||
|
||||
@ -55,8 +52,8 @@ in
|
||||
default = "";
|
||||
};
|
||||
|
||||
initPreConf = mkOption {
|
||||
type = with types; either str path;
|
||||
initPreConf = lib.mkOption {
|
||||
type = with lib.types; either str path;
|
||||
description = "The SpamAssassin init.pre config.";
|
||||
apply = val: if builtins.isPath val then val else pkgs.writeText "init.pre" val;
|
||||
default =
|
||||
@ -111,7 +108,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc."mail/spamassassin/init.pre".source = cfg.initPreConf;
|
||||
environment.etc."mail/spamassassin/local.cf".source = spamassassin-local-cf;
|
||||
|
||||
@ -185,7 +182,7 @@ in
|
||||
serviceConfig = {
|
||||
User = "spamd";
|
||||
Group = "spamd";
|
||||
ExecStart = "+${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --virtual-config-dir=%S/spamassassin/user-%u --allow-tell --pidfile=/run/spamd.pid";
|
||||
ExecStart = "+${pkgs.spamassassin}/bin/spamd ${lib.optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --virtual-config-dir=%S/spamassassin/user-%u --allow-tell --pidfile=/run/spamd.pid";
|
||||
ExecReload = "+${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
StateDirectory = "spamassassin";
|
||||
};
|
||||
|
@ -1,29 +1,26 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.stalwart-mail;
|
||||
configFormat = pkgs.formats.toml { };
|
||||
configFile = configFormat.generate "stalwart-mail.toml" cfg.settings;
|
||||
dataDir = "/var/lib/stalwart-mail";
|
||||
useLegacyStorage = versionOlder config.system.stateVersion "24.11";
|
||||
useLegacyStorage = lib.versionOlder config.system.stateVersion "24.11";
|
||||
|
||||
parsePorts = listeners: let
|
||||
parseAddresses = listeners: lib.flatten(lib.mapAttrsToList (name: value: value.bind) listeners);
|
||||
splitAddress = addr: strings.splitString ":" addr;
|
||||
extractPort = addr: strings.toInt(builtins.foldl' (a: b: b) "" (splitAddress addr));
|
||||
splitAddress = addr: lib.splitString ":" addr;
|
||||
extractPort = addr: lib.toInt(builtins.foldl' (a: b: b) "" (splitAddress addr));
|
||||
in
|
||||
builtins.map(address: extractPort address) (parseAddresses listeners);
|
||||
|
||||
in {
|
||||
options.services.stalwart-mail = {
|
||||
enable = mkEnableOption "the Stalwart all-in-one email server";
|
||||
enable = lib.mkEnableOption "the Stalwart all-in-one email server";
|
||||
|
||||
package = mkPackageOption pkgs "stalwart-mail" { };
|
||||
package = lib.mkPackageOption pkgs "stalwart-mail" { };
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to open TCP firewall ports, which are specified in
|
||||
@ -31,7 +28,7 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
inherit (configFormat) type;
|
||||
default = { };
|
||||
description = ''
|
||||
@ -43,36 +40,36 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# Default config: all local
|
||||
services.stalwart-mail.settings = {
|
||||
tracer.stdout = {
|
||||
type = mkDefault "stdout";
|
||||
level = mkDefault "info";
|
||||
ansi = mkDefault false; # no colour markers to journald
|
||||
enable = mkDefault true;
|
||||
type = lib.mkDefault "stdout";
|
||||
level = lib.mkDefault "info";
|
||||
ansi = lib.mkDefault false; # no colour markers to journald
|
||||
enable = lib.mkDefault true;
|
||||
};
|
||||
store = if useLegacyStorage then {
|
||||
# structured data in SQLite, blobs on filesystem
|
||||
db.type = mkDefault "sqlite";
|
||||
db.path = mkDefault "${dataDir}/data/index.sqlite3";
|
||||
fs.type = mkDefault "fs";
|
||||
fs.path = mkDefault "${dataDir}/data/blobs";
|
||||
db.type = lib.mkDefault "sqlite";
|
||||
db.path = lib.mkDefault "${dataDir}/data/index.sqlite3";
|
||||
fs.type = lib.mkDefault "fs";
|
||||
fs.path = lib.mkDefault "${dataDir}/data/blobs";
|
||||
} else {
|
||||
# everything in RocksDB
|
||||
db.type = mkDefault "rocksdb";
|
||||
db.path = mkDefault "${dataDir}/db";
|
||||
db.compression = mkDefault "lz4";
|
||||
db.type = lib.mkDefault "rocksdb";
|
||||
db.path = lib.mkDefault "${dataDir}/db";
|
||||
db.compression = lib.mkDefault "lz4";
|
||||
};
|
||||
storage.data = mkDefault "db";
|
||||
storage.fts = mkDefault "db";
|
||||
storage.lookup = mkDefault "db";
|
||||
storage.blob = mkDefault (if useLegacyStorage then "fs" else "db");
|
||||
directory.internal.type = mkDefault "internal";
|
||||
directory.internal.store = mkDefault "db";
|
||||
storage.directory = mkDefault "internal";
|
||||
resolver.type = mkDefault "system";
|
||||
storage.data = lib.mkDefault "db";
|
||||
storage.fts = lib.mkDefault "db";
|
||||
storage.lookup = lib.mkDefault "db";
|
||||
storage.blob = lib.mkDefault (if useLegacyStorage then "fs" else "db");
|
||||
directory.internal.type = lib.mkDefault "internal";
|
||||
directory.internal.store = lib.mkDefault "db";
|
||||
storage.directory = lib.mkDefault "internal";
|
||||
resolver.type = lib.mkDefault "system";
|
||||
resolver.public-suffix = lib.mkDefault [
|
||||
"file://${pkgs.publicsuffix-list}/share/publicsuffix/public_suffix_list.dat"
|
||||
];
|
||||
@ -155,13 +152,13 @@ in {
|
||||
# Make admin commands available in the shell
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
networking.firewall = mkIf (cfg.openFirewall
|
||||
networking.firewall = lib.mkIf (cfg.openFirewall
|
||||
&& (builtins.hasAttr "listener" cfg.settings.server)) {
|
||||
allowedTCPPorts = parsePorts cfg.settings.server.listener;
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ happysalada pacien onny ];
|
||||
maintainers = with lib.maintainers; [ happysalada pacien onny ];
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.zeyple;
|
||||
ini = pkgs.formats.ini { };
|
||||
@ -16,10 +14,10 @@ let
|
||||
'';
|
||||
in {
|
||||
options.services.zeyple = {
|
||||
enable = mkEnableOption "Zeyple, an utility program to automatically encrypt outgoing emails with GPG";
|
||||
enable = lib.mkEnableOption "Zeyple, an utility program to automatically encrypt outgoing emails with GPG";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "zeyple";
|
||||
description = ''
|
||||
User to run Zeyple as.
|
||||
@ -32,8 +30,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "zeyple";
|
||||
description = ''
|
||||
Group to use to run Zeyple.
|
||||
@ -46,7 +44,7 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = ini.type;
|
||||
default = { };
|
||||
description = ''
|
||||
@ -56,21 +54,21 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
keys = mkOption {
|
||||
type = with types; listOf path;
|
||||
keys = lib.mkOption {
|
||||
type = with lib.types; listOf path;
|
||||
description = "List of public key files that will be imported by gpg.";
|
||||
};
|
||||
|
||||
rotateLogs = mkOption {
|
||||
type = types.bool;
|
||||
rotateLogs = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable rotation of log files.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.groups = optionalAttrs (cfg.group == "zeyple") { "${cfg.group}" = { }; };
|
||||
users.users = optionalAttrs (cfg.user == "zeyple") {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.groups = lib.optionalAttrs (cfg.group == "zeyple") { "${cfg.group}" = { }; };
|
||||
users.users = lib.optionalAttrs (cfg.user == "zeyple") {
|
||||
"${cfg.user}" = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
@ -78,14 +76,14 @@ in {
|
||||
};
|
||||
|
||||
services.zeyple.settings = {
|
||||
zeyple = mapAttrs (name: mkDefault) {
|
||||
zeyple = lib.mapAttrs (name: lib.mkDefault) {
|
||||
log_file = "/var/log/zeyple/zeyple.log";
|
||||
force_encrypt = true;
|
||||
};
|
||||
|
||||
gpg = mapAttrs (name: mkDefault) { home = "${gpgHome}"; };
|
||||
gpg = lib.mapAttrs (name: lib.mkDefault) { home = "${gpgHome}"; };
|
||||
|
||||
relay = mapAttrs (name: mkDefault) {
|
||||
relay = lib.mapAttrs (name: lib.mkDefault) {
|
||||
host = "localhost";
|
||||
port = 10026;
|
||||
};
|
||||
@ -98,7 +96,7 @@ in {
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
services.logrotate = mkIf cfg.rotateLogs {
|
||||
services.logrotate = lib.mkIf cfg.rotateLogs {
|
||||
enable = true;
|
||||
settings.zeyple = {
|
||||
files = cfg.settings.zeyple.log_file;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
dataDir = "/var/lib/matrix-appservice-discord";
|
||||
registrationFile = "${dataDir}/discord-registration.yaml";
|
||||
@ -13,14 +10,14 @@ let
|
||||
in {
|
||||
options = {
|
||||
services.matrix-appservice-discord = {
|
||||
enable = mkEnableOption "a bridge between Matrix and Discord";
|
||||
enable = lib.mkEnableOption "a bridge between Matrix and Discord";
|
||||
|
||||
package = mkPackageOption pkgs "matrix-appservice-discord" { };
|
||||
package = lib.mkPackageOption pkgs "matrix-appservice-discord" { };
|
||||
|
||||
settings = mkOption rec {
|
||||
# TODO: switch to types.config.json as prescribed by RFC42 once it's implemented
|
||||
type = types.attrs;
|
||||
apply = recursiveUpdate default;
|
||||
settings = lib.mkOption rec {
|
||||
# TODO: switch to lib.types.config.json as prescribed by RFC42 once it's implemented
|
||||
type = lib.types.attrs;
|
||||
apply = lib.recursiveUpdate default;
|
||||
default = {
|
||||
database = {
|
||||
filename = "${dataDir}/discord.db";
|
||||
@ -33,7 +30,7 @@ in {
|
||||
botToken = "";
|
||||
};
|
||||
};
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
bridge = {
|
||||
domain = "public-domain.tld";
|
||||
@ -55,8 +52,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing environment variables to be passed to the matrix-appservice-discord service,
|
||||
@ -66,36 +63,36 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "http://localhost:${toString cfg.port}";
|
||||
defaultText = literalExpression ''"http://localhost:''${toString config.${opt.port}}"'';
|
||||
defaultText = lib.literalExpression ''"http://localhost:''${toString config.${opt.port}}"'';
|
||||
description = ''
|
||||
The URL where the application service is listening for HS requests.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 9005; # from https://github.com/Half-Shot/matrix-appservice-discord/blob/master/package.json#L11
|
||||
description = ''
|
||||
Port number on which the bridge should listen for internal communication with the Matrix homeserver.
|
||||
'';
|
||||
};
|
||||
|
||||
localpart = mkOption {
|
||||
type = with types; nullOr str;
|
||||
localpart = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
The user_id localpart to assign to the AS.
|
||||
'';
|
||||
};
|
||||
|
||||
serviceDependencies = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = literalExpression ''
|
||||
optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
serviceDependencies = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = lib.literalExpression ''
|
||||
lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
'';
|
||||
description = ''
|
||||
List of Systemd services to require and wait for when starting the application service,
|
||||
@ -105,7 +102,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.matrix-appservice-discord = {
|
||||
description = "A bridge between Matrix and Discord.";
|
||||
|
||||
@ -117,8 +114,8 @@ in {
|
||||
if [ ! -f '${registrationFile}' ]; then
|
||||
${cfg.package}/bin/matrix-appservice-discord \
|
||||
--generate-registration \
|
||||
--url=${escapeShellArg cfg.url} \
|
||||
${optionalString (cfg.localpart != null) "--localpart=${escapeShellArg cfg.localpart}"} \
|
||||
--url=${lib.escapeShellArg cfg.url} \
|
||||
${lib.optionalString (cfg.localpart != null) "--localpart=${lib.escapeShellArg cfg.localpart}"} \
|
||||
--config='${settingsFile}' \
|
||||
--file='${registrationFile}'
|
||||
fi
|
||||
@ -151,5 +148,5 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
meta.maintainers = with lib.maintainers; [ pacien ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-appservice-irc;
|
||||
|
||||
@ -25,29 +22,29 @@ let
|
||||
'';
|
||||
registrationFile = "/var/lib/matrix-appservice-irc/registration.yml";
|
||||
in {
|
||||
options.services.matrix-appservice-irc = with types; {
|
||||
enable = mkEnableOption "the Matrix/IRC bridge";
|
||||
options.services.matrix-appservice-irc = with lib.types; {
|
||||
enable = lib.mkEnableOption "the Matrix/IRC bridge";
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
type = port;
|
||||
description = "The port to listen on";
|
||||
default = 8009;
|
||||
};
|
||||
|
||||
needBindingCap = mkOption {
|
||||
needBindingCap = lib.mkOption {
|
||||
type = bool;
|
||||
description = "Whether the daemon needs to bind to ports below 1024 (e.g. for the ident service)";
|
||||
default = false;
|
||||
};
|
||||
|
||||
passwordEncryptionKeyLength = mkOption {
|
||||
passwordEncryptionKeyLength = lib.mkOption {
|
||||
type = ints.unsigned;
|
||||
description = "Length of the key to encrypt IRC passwords with";
|
||||
default = 4096;
|
||||
example = 8192;
|
||||
};
|
||||
|
||||
registrationUrl = mkOption {
|
||||
registrationUrl = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The URL where the application service is listening for homeserver requests,
|
||||
@ -56,13 +53,13 @@ in {
|
||||
example = "http://localhost:8009";
|
||||
};
|
||||
|
||||
localpart = mkOption {
|
||||
localpart = lib.mkOption {
|
||||
type = str;
|
||||
description = "The user_id localpart to assign to the appservice";
|
||||
default = "appservice-irc";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration for the appservice, see
|
||||
<https://github.com/matrix-org/matrix-appservice-irc/blob/${pkgs.matrix-appservice-irc.version}/config.sample.yaml>
|
||||
@ -73,19 +70,19 @@ in {
|
||||
freeformType = jsonType;
|
||||
|
||||
options = {
|
||||
homeserver = mkOption {
|
||||
homeserver = lib.mkOption {
|
||||
description = "Homeserver configuration";
|
||||
default = {};
|
||||
type = submodule {
|
||||
freeformType = jsonType;
|
||||
|
||||
options = {
|
||||
url = mkOption {
|
||||
url = lib.mkOption {
|
||||
type = str;
|
||||
description = "The URL to the home server for client-server API calls";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
domain = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The 'domain' part for user IDs on this home server. Usually
|
||||
@ -96,21 +93,21 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
database = lib.mkOption {
|
||||
default = {};
|
||||
description = "Configuration for the database";
|
||||
type = submodule {
|
||||
freeformType = jsonType;
|
||||
|
||||
options = {
|
||||
engine = mkOption {
|
||||
engine = lib.mkOption {
|
||||
type = str;
|
||||
description = "Which database engine to use";
|
||||
default = "nedb";
|
||||
example = "postgres";
|
||||
};
|
||||
|
||||
connectionString = mkOption {
|
||||
connectionString = lib.mkOption {
|
||||
type = str;
|
||||
description = "The database connection string";
|
||||
default = "nedb://var/lib/matrix-appservice-irc/data";
|
||||
@ -120,14 +117,14 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
ircService = mkOption {
|
||||
ircService = lib.mkOption {
|
||||
default = {};
|
||||
description = "IRC bridge configuration";
|
||||
type = submodule {
|
||||
freeformType = jsonType;
|
||||
|
||||
options = {
|
||||
passwordEncryptionKeyPath = mkOption {
|
||||
passwordEncryptionKeyPath = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
Location of the key with which IRC passwords are encrypted
|
||||
@ -136,7 +133,7 @@ in {
|
||||
default = "/var/lib/matrix-appservice-irc/passkey.pem";
|
||||
};
|
||||
|
||||
servers = mkOption {
|
||||
servers = lib.mkOption {
|
||||
type = submodule { freeformType = jsonType; };
|
||||
description = "IRC servers to connect to";
|
||||
};
|
||||
@ -147,7 +144,7 @@ in {
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.matrix-appservice-irc = {
|
||||
description = "Matrix-IRC bridge";
|
||||
before = [ "matrix-synapse.service" ]; # So the registration can be used by Synapse
|
||||
@ -206,7 +203,7 @@ in {
|
||||
User = "matrix-appservice-irc";
|
||||
Group = "matrix-appservice-irc";
|
||||
|
||||
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ optional (cfg.needBindingCap) "CAP_NET_BIND_SERVICE";
|
||||
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ lib.optional (cfg.needBindingCap) "CAP_NET_BIND_SERVICE";
|
||||
AmbientCapabilities = CapabilityBoundingSet;
|
||||
NoNewPrivileges = true;
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-conduit;
|
||||
|
||||
@ -9,67 +6,67 @@ let
|
||||
configFile = format.generate "conduit.toml" cfg.settings;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [ pstn ];
|
||||
meta.maintainers = with lib.maintainers; [ pstn ];
|
||||
options.services.matrix-conduit = {
|
||||
enable = mkEnableOption "matrix-conduit";
|
||||
enable = lib.mkEnableOption "matrix-conduit";
|
||||
|
||||
extraEnvironment = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
extraEnvironment = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
description = "Extra Environment variables to pass to the conduit server.";
|
||||
default = {};
|
||||
example = { RUST_BACKTRACE="yes"; };
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "matrix-conduit" { };
|
||||
package = lib.mkPackageOption pkgs "matrix-conduit" { };
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
global.server_name = mkOption {
|
||||
type = types.str;
|
||||
global.server_name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "example.com";
|
||||
description = "The server_name is the name of this server. It is used as a suffix for user # and room ids.";
|
||||
};
|
||||
global.port = mkOption {
|
||||
type = types.port;
|
||||
global.port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 6167;
|
||||
description = "The port Conduit will be running on. You need to set up a reverse proxy in your web server (e.g. apache or nginx), so all requests to /_matrix on port 443 and 8448 will be forwarded to the Conduit instance running on this port";
|
||||
};
|
||||
global.max_request_size = mkOption {
|
||||
type = types.ints.positive;
|
||||
global.max_request_size = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 20000000;
|
||||
description = "Max request size in bytes. Don't forget to also change it in the proxy.";
|
||||
};
|
||||
global.allow_registration = mkOption {
|
||||
type = types.bool;
|
||||
global.allow_registration = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether new users can register on this server.";
|
||||
};
|
||||
global.allow_encryption = mkOption {
|
||||
type = types.bool;
|
||||
global.allow_encryption = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether new encrypted rooms can be created. Note: existing rooms will continue to work.";
|
||||
};
|
||||
global.allow_federation = mkOption {
|
||||
type = types.bool;
|
||||
global.allow_federation = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether this server federates with other servers.
|
||||
'';
|
||||
};
|
||||
global.trusted_servers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
global.trusted_servers = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "matrix.org" ];
|
||||
description = "Servers trusted with signing server keys.";
|
||||
};
|
||||
global.address = mkOption {
|
||||
type = types.str;
|
||||
global.address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "::1";
|
||||
description = "Address to listen on for connections by the reverse proxy/tls terminator.";
|
||||
};
|
||||
global.database_path = mkOption {
|
||||
type = types.str;
|
||||
global.database_path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/matrix-conduit/";
|
||||
readOnly = true;
|
||||
description = ''
|
||||
@ -78,8 +75,8 @@ in
|
||||
and is set to be read only.
|
||||
'';
|
||||
};
|
||||
global.database_backend = mkOption {
|
||||
type = types.enum [ "sqlite" "rocksdb" ];
|
||||
global.database_backend = lib.mkOption {
|
||||
type = lib.types.enum [ "sqlite" "rocksdb" ];
|
||||
default = "sqlite";
|
||||
example = "rocksdb";
|
||||
description = ''
|
||||
@ -87,8 +84,8 @@ in
|
||||
instance will require manual migration of data.
|
||||
'';
|
||||
};
|
||||
global.allow_check_for_updates = mkOption {
|
||||
type = types.bool;
|
||||
global.allow_check_for_updates = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to allow Conduit to automatically contact
|
||||
@ -109,7 +106,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.conduit = {
|
||||
description = "Conduit Matrix Server";
|
||||
documentation = [ "https://gitlab.com/famedly/conduit/" ];
|
||||
|
@ -1,26 +1,23 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.mautrix-facebook;
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
settingsFile = settingsFormat.generate "mautrix-facebook-config.json" cfg.settings;
|
||||
|
||||
puppetRegex = concatStringsSep
|
||||
puppetRegex = lib.concatStringsSep
|
||||
".*"
|
||||
(map
|
||||
escapeRegex
|
||||
(splitString
|
||||
lib.escapeRegex
|
||||
(lib.splitString
|
||||
"{userid}"
|
||||
cfg.settings.bridge.username_template));
|
||||
in {
|
||||
options = {
|
||||
services.mautrix-facebook = {
|
||||
enable = mkEnableOption "Mautrix-Facebook, a Matrix-Facebook hybrid puppeting/relaybot bridge";
|
||||
enable = lib.mkEnableOption "Mautrix-Facebook, a Matrix-Facebook hybrid puppeting/relaybot bridge";
|
||||
|
||||
settings = mkOption rec {
|
||||
apply = recursiveUpdate default;
|
||||
settings = lib.mkOption rec {
|
||||
apply = lib.recursiveUpdate default;
|
||||
type = settingsFormat.type;
|
||||
default = {
|
||||
homeserver = {
|
||||
@ -70,7 +67,7 @@ in {
|
||||
};
|
||||
};
|
||||
};
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
homeserver = {
|
||||
address = "http://localhost:8008";
|
||||
@ -93,8 +90,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing environment variables to be passed to the mautrix-facebook service.
|
||||
@ -103,16 +100,16 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
configurePostgresql = mkOption {
|
||||
type = types.bool;
|
||||
configurePostgresql = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable PostgreSQL and create a user and database for mautrix-facebook. The default `settings` reference this database, if you disable this option you must provide a database URL.
|
||||
'';
|
||||
};
|
||||
|
||||
registrationData = mkOption {
|
||||
type = types.attrs;
|
||||
registrationData = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Output data for appservice registration. Simply make any desired changes and serialize to JSON. Note that this data contains secrets so think twice before putting it into the nix store.
|
||||
@ -123,7 +120,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.groups.mautrix-facebook = {};
|
||||
|
||||
users.users.mautrix-facebook = {
|
||||
@ -131,7 +128,7 @@ in {
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
services.postgresql = mkIf cfg.configurePostgresql {
|
||||
services.postgresql = lib.mkIf cfg.configurePostgresql {
|
||||
ensureDatabases = ["mautrix-facebook"];
|
||||
ensureUsers = [{
|
||||
name = "mautrix-facebook";
|
||||
@ -143,8 +140,8 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [
|
||||
"network-online.target"
|
||||
] ++ optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
++ optional cfg.configurePostgresql "postgresql.service";
|
||||
] ++ lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
++ lib.optional cfg.configurePostgresql "postgresql.service";
|
||||
after = wants;
|
||||
|
||||
serviceConfig = {
|
||||
@ -176,11 +173,11 @@ in {
|
||||
users = [
|
||||
{
|
||||
exclusive = true;
|
||||
regex = escapeRegex "@${cfg.settings.appservice.bot_username}:${cfg.settings.homeserver.domain}";
|
||||
regex = lib.escapeRegex "@${cfg.settings.appservice.bot_username}:${cfg.settings.homeserver.domain}";
|
||||
}
|
||||
{
|
||||
exclusive = true;
|
||||
regex = "@${puppetRegex}:${escapeRegex cfg.settings.homeserver.domain}";
|
||||
regex = "@${puppetRegex}:${lib.escapeRegex cfg.settings.homeserver.domain}";
|
||||
}
|
||||
];
|
||||
aliases = [];
|
||||
@ -196,5 +193,5 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ kevincox ];
|
||||
meta.maintainers = with lib.maintainers; [ kevincox ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
dataDir = "/var/lib/mautrix-telegram";
|
||||
registrationFile = "${dataDir}/telegram-registration.yaml";
|
||||
@ -13,10 +10,10 @@ let
|
||||
in {
|
||||
options = {
|
||||
services.mautrix-telegram = {
|
||||
enable = mkEnableOption "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge";
|
||||
enable = lib.mkEnableOption "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge";
|
||||
|
||||
settings = mkOption rec {
|
||||
apply = recursiveUpdate default;
|
||||
settings = lib.mkOption rec {
|
||||
apply = lib.recursiveUpdate default;
|
||||
inherit (settingsFormat) type;
|
||||
default = {
|
||||
homeserver = {
|
||||
@ -64,7 +61,7 @@ in {
|
||||
};
|
||||
};
|
||||
};
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
homeserver = {
|
||||
address = "http://localhost:8008";
|
||||
@ -95,8 +92,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing environment variables to be passed to the mautrix-telegram service,
|
||||
@ -120,11 +117,11 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
serviceDependencies = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = literalExpression ''
|
||||
optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
serviceDependencies = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = lib.literalExpression ''
|
||||
lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
'';
|
||||
description = ''
|
||||
List of Systemd services to require and wait for when starting the application service.
|
||||
@ -133,7 +130,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.mautrix-telegram = {
|
||||
description = "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge.";
|
||||
|
||||
@ -192,5 +189,5 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ pacien vskilet ];
|
||||
meta.maintainers = with lib.maintainers; [ pacien vskilet ];
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.mjolnir;
|
||||
|
||||
@ -25,8 +23,8 @@ let
|
||||
};
|
||||
|
||||
moduleConfigFile = pkgs.writeText "module-config.yaml" (
|
||||
generators.toYAML { } (filterAttrs (_: v: v != null)
|
||||
(fold recursiveUpdate { } [ yamlConfig cfg.settings ])));
|
||||
lib.generators.toYAML { } (lib.filterAttrs (_: v: v != null)
|
||||
(lib.fold lib.recursiveUpdate { } [ yamlConfig cfg.settings ])));
|
||||
|
||||
# these config files will be merged one after the other to build the final config
|
||||
configFiles = [
|
||||
@ -38,8 +36,8 @@ let
|
||||
# replace all secret strings using replace-secret
|
||||
generateConfig = pkgs.writeShellScript "mjolnir-generate-config" (
|
||||
let
|
||||
yqEvalStr = concatImapStringsSep " * " (pos: _: "select(fileIndex == ${toString (pos - 1)})") configFiles;
|
||||
yqEvalArgs = concatStringsSep " " configFiles;
|
||||
yqEvalStr = lib.concatImapStringsSep " * " (pos: _: "select(fileIndex == ${toString (pos - 1)})") configFiles;
|
||||
yqEvalArgs = lib.concatStringsSep " " configFiles;
|
||||
in
|
||||
''
|
||||
set -euo pipefail
|
||||
@ -54,10 +52,10 @@ let
|
||||
# e.g. "eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' filea.yaml fileb.yaml" will merge filea.yaml with fileb.yaml
|
||||
${pkgs.yq-go}/bin/yq eval-all -P '${yqEvalStr}' ${yqEvalArgs} > ${cfg.dataPath}/config/default.yaml
|
||||
|
||||
${optionalString (cfg.accessTokenFile != null) ''
|
||||
${lib.optionalString (cfg.accessTokenFile != null) ''
|
||||
${pkgs.replace-secret}/bin/replace-secret '@ACCESS_TOKEN@' '${cfg.accessTokenFile}' ${cfg.dataPath}/config/default.yaml
|
||||
''}
|
||||
${optionalString (cfg.pantalaimon.passwordFile != null) ''
|
||||
${lib.optionalString (cfg.pantalaimon.passwordFile != null) ''
|
||||
${pkgs.replace-secret}/bin/replace-secret '@PANTALAIMON_PASSWORD@' '${cfg.pantalaimon.passwordFile}' ${cfg.dataPath}/config/default.yaml
|
||||
''}
|
||||
''
|
||||
@ -65,10 +63,10 @@ let
|
||||
in
|
||||
{
|
||||
options.services.mjolnir = {
|
||||
enable = mkEnableOption "Mjolnir, a moderation tool for Matrix";
|
||||
enable = lib.mkEnableOption "Mjolnir, a moderation tool for Matrix";
|
||||
|
||||
homeserverUrl = mkOption {
|
||||
type = types.str;
|
||||
homeserverUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "https://matrix.org";
|
||||
description = ''
|
||||
Where the homeserver is located (client-server URL).
|
||||
@ -78,43 +76,43 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
accessTokenFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
accessTokenFile = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing the matrix access token for the `mjolnir` user.
|
||||
'';
|
||||
};
|
||||
|
||||
pantalaimon = mkOption {
|
||||
pantalaimon = lib.mkOption {
|
||||
description = ''
|
||||
`pantalaimon` options (enables E2E Encryption support).
|
||||
|
||||
This will create a `pantalaimon` instance with the name "mjolnir".
|
||||
'';
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
ignoring the accessToken. If true, accessToken is ignored and the username/password below will be
|
||||
used instead. The access token of the bot will be stored in the dataPath
|
||||
'';
|
||||
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The username to login with.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
passwordFile = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing the matrix password for the `mjolnir` user.
|
||||
'';
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
type = types.submodule (import ./pantalaimon-options.nix);
|
||||
options = lib.mkOption {
|
||||
type = lib.types.submodule (import ./pantalaimon-options.nix);
|
||||
default = { };
|
||||
description = ''
|
||||
passthrough additional options to the `pantalaimon` service.
|
||||
@ -124,16 +122,16 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
dataPath = mkOption {
|
||||
type = types.path;
|
||||
dataPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/mjolnir";
|
||||
description = ''
|
||||
The directory the bot should store various bits of information in.
|
||||
'';
|
||||
};
|
||||
|
||||
managementRoom = mkOption {
|
||||
type = types.str;
|
||||
managementRoom = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "#moderators:example.org";
|
||||
description = ''
|
||||
The room ID where people can use the bot. The bot has no access controls, so
|
||||
@ -143,10 +141,10 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
protectedRooms = mkOption {
|
||||
type = types.listOf types.str;
|
||||
protectedRooms = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
[
|
||||
"https://matrix.to/#/#yourroom:example.org"
|
||||
"https://matrix.to/#/#anotherroom:example.org"
|
||||
@ -157,10 +155,10 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
default = { };
|
||||
type = (pkgs.formats.yaml { }).type;
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
autojoinOnlyIfManager = true;
|
||||
automaticallyRedactForReasons = [ "spam" "advertising" ];
|
||||
@ -172,7 +170,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.mjolnir.enable {
|
||||
config = lib.mkIf config.services.mjolnir.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(cfg.pantalaimon.enable && cfg.pantalaimon.passwordFile == null);
|
||||
@ -188,15 +186,15 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
services.pantalaimon-headless.instances."mjolnir" = mkIf cfg.pantalaimon.enable
|
||||
services.pantalaimon-headless.instances."mjolnir" = lib.mkIf cfg.pantalaimon.enable
|
||||
{
|
||||
homeserver = cfg.homeserverUrl;
|
||||
} // cfg.pantalaimon.options;
|
||||
|
||||
systemd.services.mjolnir = {
|
||||
description = "mjolnir - a moderation tool for Matrix";
|
||||
wants = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
|
||||
after = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
|
||||
wants = [ "network-online.target" ] ++ lib.optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
|
||||
after = [ "network-online.target" ] ++ lib.optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
@ -216,10 +214,10 @@ in
|
||||
/* TODO: wait for #102397 to be resolved. Then load secrets from $CREDENTIALS_DIRECTORY+"/NAME"
|
||||
DynamicUser = true;
|
||||
LoadCredential = [] ++
|
||||
optionals (cfg.accessTokenFile != null) [
|
||||
lib.optionals (cfg.accessTokenFile != null) [
|
||||
"access_token:${cfg.accessTokenFile}"
|
||||
] ++
|
||||
optionals (cfg.pantalaimon.passwordFile != null) [
|
||||
lib.optionals (cfg.pantalaimon.passwordFile != null) [
|
||||
"pantalaimon_password:${cfg.pantalaimon.passwordFile}"
|
||||
];
|
||||
*/
|
||||
@ -237,6 +235,6 @@ in
|
||||
|
||||
meta = {
|
||||
doc = ./mjolnir.md;
|
||||
maintainers = with maintainers; [ jojosch ];
|
||||
maintainers = with lib.maintainers; [ jojosch ];
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
dataDir = "/var/lib/mx-puppet-discord";
|
||||
registrationFile = "${dataDir}/discord-registration.yaml";
|
||||
@ -12,13 +9,13 @@ let
|
||||
in {
|
||||
options = {
|
||||
services.mx-puppet-discord = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
mx-puppet-discord is a discord puppeting bridge for matrix.
|
||||
It handles bridging private and group DMs, as well as Guilds (servers)
|
||||
'';
|
||||
|
||||
settings = mkOption rec {
|
||||
apply = recursiveUpdate default;
|
||||
settings = lib.mkOption rec {
|
||||
apply = lib.recursiveUpdate default;
|
||||
inherit (settingsFormat) type;
|
||||
default = {
|
||||
bridge.port = 8434;
|
||||
@ -45,7 +42,7 @@ in {
|
||||
lineDateFormat = "MMM-D HH:mm:ss.SSS";
|
||||
};
|
||||
};
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
bridge = {
|
||||
bindAddress = "localhost";
|
||||
@ -64,11 +61,11 @@ in {
|
||||
sample.config.yaml](https://github.com/matrix-discord/mx-puppet-discord/blob/master/sample.config.yaml).
|
||||
'';
|
||||
};
|
||||
serviceDependencies = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = literalExpression ''
|
||||
optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
serviceDependencies = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
|
||||
defaultText = lib.literalExpression ''
|
||||
lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
|
||||
'';
|
||||
description = ''
|
||||
List of Systemd services to require and wait for when starting the application service.
|
||||
@ -77,7 +74,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.mx-puppet-discord = {
|
||||
description = "Matrix to Discord puppeting bridge";
|
||||
|
||||
@ -118,5 +115,5 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ govanify ];
|
||||
meta.maintainers = with lib.maintainers; [ govanify ];
|
||||
}
|
||||
|
@ -1,26 +1,24 @@
|
||||
{ config, lib, name, ... }:
|
||||
|
||||
with lib;
|
||||
{
|
||||
options = {
|
||||
dataPath = mkOption {
|
||||
type = types.path;
|
||||
dataPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/pantalaimon-${name}";
|
||||
description = ''
|
||||
The directory where `pantalaimon` should store its state such as the database file.
|
||||
'';
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "info" "warning" "error" "debug" ];
|
||||
logLevel = lib.mkOption {
|
||||
type = lib.types.enum [ "info" "warning" "error" "debug" ];
|
||||
default = "warning";
|
||||
description = ''
|
||||
Set the log level of the daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
homeserver = mkOption {
|
||||
type = types.str;
|
||||
homeserver = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "https://matrix.org";
|
||||
description = ''
|
||||
The URI of the homeserver that the `pantalaimon` proxy should
|
||||
@ -29,8 +27,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
ssl = mkOption {
|
||||
type = types.bool;
|
||||
ssl = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether or not SSL verification should be enabled for outgoing
|
||||
@ -38,8 +36,8 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
The address where the daemon will listen to client connections
|
||||
@ -47,18 +45,18 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
listenPort = mkOption {
|
||||
type = types.port;
|
||||
listenPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8009;
|
||||
description = ''
|
||||
The port where the daemon will listen to client connections for
|
||||
this homeserver. Note that the listen address/port combination
|
||||
needs to be unique between different homeservers.
|
||||
needs to be lib.unique between different homeservers.
|
||||
'';
|
||||
};
|
||||
|
||||
extraSettings = mkOption {
|
||||
type = types.attrs;
|
||||
extraSettings = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
Extra configuration options. See
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.pantalaimon-headless;
|
||||
|
||||
@ -12,7 +10,7 @@ let
|
||||
Notifications = false;
|
||||
};
|
||||
|
||||
${name} = (recursiveUpdate
|
||||
${name} = (lib.recursiveUpdate
|
||||
{
|
||||
Homeserver = instanceConfig.homeserver;
|
||||
ListenAddress = instanceConfig.listenAddress;
|
||||
@ -28,7 +26,7 @@ let
|
||||
};
|
||||
|
||||
mkPantalaimonService = name: instanceConfig:
|
||||
nameValuePair "pantalaimon-${name}" {
|
||||
lib.nameValuePair "pantalaimon-${name}" {
|
||||
description = "pantalaimon instance ${name} - E2EE aware proxy daemon for matrix clients";
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
@ -48,9 +46,9 @@ let
|
||||
};
|
||||
in
|
||||
{
|
||||
options.services.pantalaimon-headless.instances = mkOption {
|
||||
options.services.pantalaimon-headless.instances = lib.mkOption {
|
||||
default = { };
|
||||
type = types.attrsOf (types.submodule (import ./pantalaimon-options.nix));
|
||||
type = lib.types.attrsOf (lib.types.submodule (import ./pantalaimon-options.nix));
|
||||
description = ''
|
||||
Declarative instance config.
|
||||
|
||||
@ -59,12 +57,12 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf (config.services.pantalaimon-headless.instances != { })
|
||||
config = lib.mkIf (config.services.pantalaimon-headless.instances != { })
|
||||
{
|
||||
systemd.services = mapAttrs' mkPantalaimonService config.services.pantalaimon-headless.instances;
|
||||
systemd.services = lib.mapAttrs' mkPantalaimonService config.services.pantalaimon-headless.instances;
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ jojosch ];
|
||||
maintainers = with lib.maintainers; [ jojosch ];
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.airsonic;
|
||||
opt = options.services.airsonic;
|
||||
@ -9,16 +6,16 @@ in {
|
||||
options = {
|
||||
|
||||
services.airsonic = {
|
||||
enable = mkEnableOption "Airsonic, the Free and Open Source media streaming server (fork of Subsonic and Libresonic)";
|
||||
enable = lib.mkEnableOption "Airsonic, the Free and Open Source media streaming server (fork of Subsonic and Libresonic)";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "airsonic";
|
||||
description = "User account under which airsonic runs.";
|
||||
};
|
||||
|
||||
home = mkOption {
|
||||
type = types.path;
|
||||
home = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/airsonic";
|
||||
description = ''
|
||||
The directory where Airsonic will create files.
|
||||
@ -26,16 +23,16 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
virtualHost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
virtualHost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost.
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = ''
|
||||
The host name or IP address on which to bind Airsonic.
|
||||
@ -47,8 +44,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 4040;
|
||||
description = ''
|
||||
The port on which Airsonic will listen for
|
||||
@ -56,8 +53,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
contextPath = mkOption {
|
||||
type = types.path;
|
||||
contextPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/";
|
||||
description = ''
|
||||
The context path, i.e., the last part of the Airsonic
|
||||
@ -65,8 +62,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
maxMemory = mkOption {
|
||||
type = types.int;
|
||||
maxMemory = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 100;
|
||||
description = ''
|
||||
The memory limit (max Java heap size) in megabytes.
|
||||
@ -74,10 +71,10 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
transcoders = mkOption {
|
||||
type = types.listOf types.path;
|
||||
transcoders = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [ "${pkgs.ffmpeg.bin}/bin/ffmpeg" ];
|
||||
defaultText = literalExpression ''[ "''${pkgs.ffmpeg.bin}/bin/ffmpeg" ]'';
|
||||
defaultText = lib.literalExpression ''[ "''${pkgs.ffmpeg.bin}/bin/ffmpeg" ]'';
|
||||
description = ''
|
||||
List of paths to transcoder executables that should be accessible
|
||||
from Airsonic. Symlinks will be created to each executable inside
|
||||
@ -85,7 +82,7 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
jre = mkPackageOption pkgs "jre8" {
|
||||
jre = lib.mkPackageOption pkgs "jre8" {
|
||||
extraDescription = ''
|
||||
::: {.note}
|
||||
Airsonic only supports Java 8, airsonic-advanced requires at least
|
||||
@ -94,14 +91,14 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
war = mkOption {
|
||||
type = types.path;
|
||||
war = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${pkgs.airsonic}/webapps/airsonic.war";
|
||||
defaultText = literalExpression ''"''${pkgs.airsonic}/webapps/airsonic.war"'';
|
||||
defaultText = lib.literalExpression ''"''${pkgs.airsonic}/webapps/airsonic.war"'';
|
||||
description = "Airsonic war file to use.";
|
||||
};
|
||||
|
||||
jvmOptions = mkOption {
|
||||
jvmOptions = lib.mkOption {
|
||||
description = ''
|
||||
Extra command line options for the JVM running AirSonic.
|
||||
Useful for sending jukebox output to non-default alsa
|
||||
@ -109,7 +106,7 @@ in {
|
||||
'';
|
||||
default = [
|
||||
];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
example = [
|
||||
"-Djavax.sound.sampled.Clip='#CODEC [plughw:1,0]'"
|
||||
"-Djavax.sound.sampled.Port='#Port CODEC [hw:1]'"
|
||||
@ -121,7 +118,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.airsonic = {
|
||||
description = "Airsonic Media Server";
|
||||
after = [ "network.target" ];
|
||||
@ -143,7 +140,7 @@ in {
|
||||
-Dserver.port=${toString cfg.port} \
|
||||
-Dserver.context-path=${cfg.contextPath} \
|
||||
-Djava.awt.headless=true \
|
||||
${optionalString (cfg.virtualHost != null)
|
||||
${lib.optionalString (cfg.virtualHost != null)
|
||||
"-Dserver.use-forward-headers=true"} \
|
||||
${toString cfg.jvmOptions} \
|
||||
-verbose:gc \
|
||||
@ -155,7 +152,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = mkIf (cfg.virtualHost != null) {
|
||||
services.nginx = lib.mkIf (cfg.virtualHost != null) {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts.${cfg.virtualHost} = {
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.amazon-ssm-agent;
|
||||
|
||||
@ -22,16 +20,16 @@ let
|
||||
};
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "ssm-agent" "enable" ] [ "services" "amazon-ssm-agent" "enable" ])
|
||||
(mkRenamedOptionModule [ "services" "ssm-agent" "package" ] [ "services" "amazon-ssm-agent" "package" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "ssm-agent" "enable" ] [ "services" "amazon-ssm-agent" "enable" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "ssm-agent" "package" ] [ "services" "amazon-ssm-agent" "package" ])
|
||||
];
|
||||
|
||||
options.services.amazon-ssm-agent = {
|
||||
enable = mkEnableOption "Amazon SSM agent";
|
||||
package = mkPackageOption pkgs "amazon-ssm-agent" {};
|
||||
enable = lib.mkEnableOption "Amazon SSM agent";
|
||||
package = lib.mkPackageOption pkgs "amazon-ssm-agent" {};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# See https://github.com/aws/amazon-ssm-agent/blob/mainline/packaging/linux/amazon-ssm-agent.service
|
||||
systemd.services.amazon-ssm-agent = {
|
||||
inherit (cfg.package.meta) description;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.ankisyncd;
|
||||
|
||||
@ -22,37 +19,37 @@ let
|
||||
in
|
||||
{
|
||||
options.services.ankisyncd = {
|
||||
enable = mkEnableOption "ankisyncd, a standalone unofficial anky sync server";
|
||||
enable = lib.mkEnableOption "ankisyncd, a standalone unofficial anky sync server";
|
||||
|
||||
package = mkPackageOption pkgs "ankisyncd" { };
|
||||
package = lib.mkPackageOption pkgs "ankisyncd" { };
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = "ankisyncd host";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 27701;
|
||||
description = "ankisyncd port";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
openFirewall = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
warnings = [
|
||||
''
|
||||
`services.ankisyncd` has been replaced by `services.anki-sync-server` and will be removed after
|
||||
24.05 because anki-sync-server(-rs and python) are not maintained.
|
||||
''
|
||||
];
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
systemd.services.ankisyncd = {
|
||||
description = "ankisyncd - Anki sync server";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.apache-kafka;
|
||||
|
||||
@ -17,24 +14,24 @@ let
|
||||
|
||||
mkPropertyString = let
|
||||
render = {
|
||||
bool = boolToString;
|
||||
bool = lib.boolToString;
|
||||
int = toString;
|
||||
list = concatMapStringsSep "," mkPropertyString;
|
||||
string = id;
|
||||
list = lib.concatMapStringsSep "," mkPropertyString;
|
||||
string = lib.id;
|
||||
};
|
||||
in
|
||||
v: render.${builtins.typeOf v} v;
|
||||
|
||||
stringlySettings = mapAttrs (_: mkPropertyString)
|
||||
(filterAttrs (_: v: v != null) cfg.settings);
|
||||
stringlySettings = lib.mapAttrs (_: mkPropertyString)
|
||||
(lib.filterAttrs (_: v: v != null) cfg.settings);
|
||||
|
||||
generator = (pkgs.formats.javaProperties {}).generate;
|
||||
in {
|
||||
|
||||
options.services.apache-kafka = {
|
||||
enable = mkEnableOption "Apache Kafka event streaming broker";
|
||||
enable = lib.mkEnableOption "Apache Kafka event streaming broker";
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
[Kafka broker configuration](https://kafka.apache.org/documentation.html#brokerconfigs)
|
||||
{file}`server.properties`.
|
||||
@ -44,81 +41,81 @@ in {
|
||||
but instead as quoted strings (ie. `settings."broker.id"`, NOT
|
||||
`settings.broker.id`).
|
||||
'';
|
||||
type = types.submodule {
|
||||
freeformType = with types; let
|
||||
type = lib.types.submodule {
|
||||
freeformType = with lib.types; let
|
||||
primitive = oneOf [bool int str];
|
||||
in lazyAttrsOf (nullOr (either primitive (listOf primitive)));
|
||||
|
||||
options = {
|
||||
"broker.id" = mkOption {
|
||||
"broker.id" = lib.mkOption {
|
||||
description = "Broker ID. -1 or null to auto-allocate in zookeeper mode.";
|
||||
default = null;
|
||||
type = with types; nullOr int;
|
||||
type = with lib.types; nullOr int;
|
||||
};
|
||||
|
||||
"log.dirs" = mkOption {
|
||||
"log.dirs" = lib.mkOption {
|
||||
description = "Log file directories.";
|
||||
# Deliberaly leave out old default and use the rewrite opportunity
|
||||
# to have users choose a safer value -- /tmp might be volatile and is a
|
||||
# slightly scary default choice.
|
||||
# default = [ "/tmp/apache-kafka" ];
|
||||
type = with types; listOf path;
|
||||
type = with lib.types; listOf path;
|
||||
};
|
||||
|
||||
"listeners" = mkOption {
|
||||
"listeners" = lib.mkOption {
|
||||
description = ''
|
||||
Kafka Listener List.
|
||||
See [listeners](https://kafka.apache.org/documentation/#brokerconfigs_listeners).
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "PLAINTEXT://localhost:9092" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
clusterId = mkOption {
|
||||
clusterId = lib.mkOption {
|
||||
description = ''
|
||||
KRaft mode ClusterId used for formatting log directories. Can be generated with `kafka-storage.sh random-uuid`
|
||||
'';
|
||||
type = with types; nullOr str;
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
configFiles.serverProperties = mkOption {
|
||||
configFiles.serverProperties = lib.mkOption {
|
||||
description = ''
|
||||
Kafka server.properties configuration file path.
|
||||
Defaults to the rendered `settings`.
|
||||
'';
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
};
|
||||
|
||||
configFiles.log4jProperties = mkOption {
|
||||
configFiles.log4jProperties = lib.mkOption {
|
||||
description = "Kafka log4j property configuration file path";
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
default = pkgs.writeText "log4j.properties" cfg.log4jProperties;
|
||||
defaultText = ''pkgs.writeText "log4j.properties" cfg.log4jProperties'';
|
||||
};
|
||||
|
||||
formatLogDirs = mkOption {
|
||||
formatLogDirs = lib.mkOption {
|
||||
description = ''
|
||||
Whether to format log dirs in KRaft mode if all log dirs are
|
||||
unformatted, ie. they contain no meta.properties.
|
||||
'';
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
formatLogDirsIgnoreFormatted = mkOption {
|
||||
formatLogDirsIgnoreFormatted = lib.mkOption {
|
||||
description = ''
|
||||
Whether to ignore already formatted log dirs when formatting log dirs,
|
||||
instead of failing. Useful when replacing or adding disks.
|
||||
'';
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
log4jProperties = mkOption {
|
||||
log4jProperties = lib.mkOption {
|
||||
description = "Kafka log4j property configuration.";
|
||||
default = ''
|
||||
log4j.rootLogger=INFO, stdout
|
||||
@ -127,13 +124,13 @@ in {
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n
|
||||
'';
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
};
|
||||
|
||||
jvmOptions = mkOption {
|
||||
jvmOptions = lib.mkOption {
|
||||
description = "Extra command line options for the JVM running Kafka.";
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
example = [
|
||||
"-Djava.net.preferIPv4Stack=true"
|
||||
"-Dcom.sun.management.jmxremote"
|
||||
@ -141,38 +138,38 @@ in {
|
||||
];
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "apacheKafka" { };
|
||||
package = lib.mkPackageOption pkgs "apacheKafka" { };
|
||||
|
||||
jre = mkOption {
|
||||
jre = lib.mkOption {
|
||||
description = "The JRE with which to run Kafka";
|
||||
default = cfg.package.passthru.jre;
|
||||
defaultText = literalExpression "pkgs.apacheKafka.passthru.jre";
|
||||
type = types.package;
|
||||
defaultText = lib.literalExpression "pkgs.apacheKafka.passthru.jre";
|
||||
type = lib.types.package;
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "apache-kafka" "brokerId" ]
|
||||
[ "services" "apache-kafka" "settings" ''broker.id'' ])
|
||||
(mkRenamedOptionModule
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "apache-kafka" "logDirs" ]
|
||||
[ "services" "apache-kafka" "settings" ''log.dirs'' ])
|
||||
(mkRenamedOptionModule
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "apache-kafka" "zookeeper" ]
|
||||
[ "services" "apache-kafka" "settings" ''zookeeper.connect'' ])
|
||||
|
||||
(mkRemovedOptionModule [ "services" "apache-kafka" "port" ]
|
||||
(lib.mkRemovedOptionModule [ "services" "apache-kafka" "port" ]
|
||||
"Please see services.apache-kafka.settings.listeners and its documentation instead")
|
||||
(mkRemovedOptionModule [ "services" "apache-kafka" "hostname" ]
|
||||
(lib.mkRemovedOptionModule [ "services" "apache-kafka" "hostname" ]
|
||||
"Please see services.apache-kafka.settings.listeners and its documentation instead")
|
||||
(mkRemovedOptionModule [ "services" "apache-kafka" "extraProperties" ]
|
||||
(lib.mkRemovedOptionModule [ "services" "apache-kafka" "extraProperties" ]
|
||||
"Please see services.apache-kafka.settings and its documentation instead")
|
||||
(mkRemovedOptionModule [ "services" "apache-kafka" "serverProperties" ]
|
||||
(lib.mkRemovedOptionModule [ "services" "apache-kafka" "serverProperties" ]
|
||||
"Please see services.apache-kafka.settings and its documentation instead")
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.apache-kafka.configFiles.serverProperties = generator "server.properties" stringlySettings;
|
||||
|
||||
users.users.apache-kafka = {
|
||||
@ -188,11 +185,11 @@ in {
|
||||
description = "Apache Kafka Daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
preStart = mkIf cfg.formatLogDirs
|
||||
preStart = lib.mkIf cfg.formatLogDirs
|
||||
(if cfg.formatLogDirsIgnoreFormatted then ''
|
||||
${cfg.package}/bin/kafka-storage.sh format -t "${cfg.clusterId}" -c ${cfg.configFiles.serverProperties} --ignore-formatted
|
||||
'' else ''
|
||||
if ${concatMapStringsSep " && " (l: ''[ ! -f "${l}/meta.properties" ]'') cfg.settings."log.dirs"}; then
|
||||
if ${lib.concatMapStringsSep " && " (l: ''[ ! -f "${l}/meta.properties" ]'') cfg.settings."log.dirs"}; then
|
||||
${cfg.package}/bin/kafka-storage.sh format -t "${cfg.clusterId}" -c ${cfg.configFiles.serverProperties}
|
||||
fi
|
||||
'');
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.autofs;
|
||||
@ -18,8 +15,8 @@ in
|
||||
|
||||
services.autofs = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Mount filesystems on demand. Unmount them automatically.
|
||||
@ -27,9 +24,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
autoMaster = mkOption {
|
||||
type = types.str;
|
||||
example = literalExpression ''
|
||||
autoMaster = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = lib.literalExpression ''
|
||||
let
|
||||
mapConf = pkgs.writeText "auto" '''
|
||||
kernel -ro,soft,intr ftp.kernel.org:/pub/linux
|
||||
@ -51,14 +48,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
timeout = mkOption {
|
||||
type = types.int;
|
||||
timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 600;
|
||||
description = "Set the global minimum timeout, in seconds, until directories are unmounted";
|
||||
};
|
||||
|
||||
debug = mkOption {
|
||||
type = types.bool;
|
||||
debug = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Pass -d and -7 to automount and write log to the system journal.
|
||||
@ -72,7 +69,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
boot.kernelModules = [ "autofs" ];
|
||||
|
||||
@ -90,7 +87,7 @@ in
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
PIDFile = "/run/autofs.pid";
|
||||
ExecStart = "${pkgs.autofs5}/bin/automount ${optionalString cfg.debug "-d"} -p /run/autofs.pid -t ${builtins.toString cfg.timeout} ${autoMaster}";
|
||||
ExecStart = "${pkgs.autofs5}/bin/automount ${lib.optionalString cfg.debug "-d"} -p /run/autofs.pid -t ${builtins.toString cfg.timeout} ${autoMaster}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
};
|
||||
};
|
||||
|
@ -1,42 +1,39 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.bazarr;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.bazarr = {
|
||||
enable = mkEnableOption "bazarr, a subtitle manager for Sonarr and Radarr";
|
||||
enable = lib.mkEnableOption "bazarr, a subtitle manager for Sonarr and Radarr";
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for the bazarr web interface.";
|
||||
};
|
||||
|
||||
listenPort = mkOption {
|
||||
type = types.port;
|
||||
listenPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 6767;
|
||||
description = "Port on which the bazarr web interface should listen";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "bazarr";
|
||||
description = "User account under which bazarr runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "bazarr";
|
||||
description = "Group under which bazarr runs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.bazarr = {
|
||||
description = "bazarr";
|
||||
after = [ "network.target" ];
|
||||
@ -58,11 +55,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.listenPort ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "bazarr") {
|
||||
users.users = lib.mkIf (cfg.user == "bazarr") {
|
||||
bazarr = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
@ -70,7 +67,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "bazarr") {
|
||||
users.groups = lib.mkIf (cfg.group == "bazarr") {
|
||||
bazarr = {};
|
||||
};
|
||||
};
|
||||
|
@ -4,13 +4,10 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.bcg;
|
||||
configFile = (pkgs.formats.yaml {}).generate "bcg.conf.yaml" (
|
||||
filterAttrsRecursive (n: v: v != null) {
|
||||
lib.filterAttrsRecursive (n: v: v != null) {
|
||||
inherit (cfg) device name mqtt;
|
||||
retain_node_messages = cfg.retainNodeMessages;
|
||||
qos_node_messages = cfg.qosNodeMessages;
|
||||
@ -25,10 +22,10 @@ in
|
||||
{
|
||||
options = {
|
||||
services.bcg = {
|
||||
enable = mkEnableOption "BigClown gateway";
|
||||
package = mkPackageOption pkgs [ "python3Packages" "bcg" ] { };
|
||||
environmentFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
enable = lib.mkEnableOption "BigClown gateway";
|
||||
package = lib.mkPackageOption pkgs [ "python3Packages" "bcg" ] { };
|
||||
environmentFiles = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
example = [ "/run/keys/bcg.env" ];
|
||||
description = ''
|
||||
@ -38,17 +35,17 @@ in
|
||||
This is useful to avoid putting secrets into the nix store.
|
||||
'';
|
||||
};
|
||||
verbose = mkOption {
|
||||
type = types.enum ["CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG"];
|
||||
verbose = lib.mkOption {
|
||||
type = lib.types.enum ["CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG"];
|
||||
default = "WARNING";
|
||||
description = "Verbosity level.";
|
||||
};
|
||||
device = mkOption {
|
||||
type = types.str;
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Device name to configure gateway to use.";
|
||||
};
|
||||
name = mkOption {
|
||||
type = with types; nullOr str;
|
||||
name = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Name for the device.
|
||||
@ -61,86 +58,86 @@ in
|
||||
'';
|
||||
};
|
||||
mqtt = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Host where MQTT server is running.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 1883;
|
||||
description = "Port of MQTT server.";
|
||||
};
|
||||
username = mkOption {
|
||||
type = with types; nullOr str;
|
||||
username = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = "MQTT server access username.";
|
||||
};
|
||||
password = mkOption {
|
||||
type = with types; nullOr str;
|
||||
password = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = "MQTT server access password.";
|
||||
};
|
||||
cafile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
cafile = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = "Certificate Authority file for MQTT server access.";
|
||||
};
|
||||
certfile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
certfile = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = "Certificate file for MQTT server access.";
|
||||
};
|
||||
keyfile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
keyfile = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = "Key file for MQTT server access.";
|
||||
};
|
||||
};
|
||||
retainNodeMessages = mkOption {
|
||||
type = types.bool;
|
||||
retainNodeMessages = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Specify that node messages should be retaied in MQTT broker.";
|
||||
};
|
||||
qosNodeMessages = mkOption {
|
||||
type = types.int;
|
||||
qosNodeMessages = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 1;
|
||||
description = "Set the guarantee of MQTT message delivery.";
|
||||
};
|
||||
baseTopicPrefix = mkOption {
|
||||
type = types.str;
|
||||
baseTopicPrefix = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Topic prefix added to all MQTT messages.";
|
||||
};
|
||||
automaticRemoveKitFromNames = mkOption {
|
||||
type = types.bool;
|
||||
automaticRemoveKitFromNames = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Automatically remove kits.";
|
||||
};
|
||||
automaticRenameKitNodes = mkOption {
|
||||
type = types.bool;
|
||||
automaticRenameKitNodes = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Automatically rename kit's nodes.";
|
||||
};
|
||||
automaticRenameGenericNodes = mkOption {
|
||||
type = types.bool;
|
||||
automaticRenameGenericNodes = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Automatically rename generic nodes.";
|
||||
};
|
||||
automaticRenameNodes = mkOption {
|
||||
type = types.bool;
|
||||
automaticRenameNodes = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Automatically rename all nodes.";
|
||||
};
|
||||
rename = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
rename = lib.mkOption {
|
||||
type = with lib.types; attrsOf str;
|
||||
default = {};
|
||||
description = "Rename nodes to different name.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
python3Packages.bcg
|
||||
python3Packages.bch
|
||||
@ -156,7 +153,7 @@ in
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ] ++ lib.optional config.services.mosquitto.enable "mosquitto.service";
|
||||
after = [ "network-online.target" ];
|
||||
preStart = mkIf envConfig ''
|
||||
preStart = lib.mkIf envConfig ''
|
||||
umask 077
|
||||
${pkgs.envsubst}/bin/envsubst -i "${configFile}" -o "${finalConfig}"
|
||||
'';
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.beanstalkd;
|
||||
pkg = pkgs.beanstalkd;
|
||||
@ -12,25 +9,25 @@ in
|
||||
|
||||
options = {
|
||||
services.beanstalkd = {
|
||||
enable = mkEnableOption "the Beanstalk work queue";
|
||||
enable = lib.mkEnableOption "the Beanstalk work queue";
|
||||
|
||||
listen = {
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "TCP port that will be used to accept client connections.";
|
||||
default = 11300;
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "IP address to listen on.";
|
||||
default = "127.0.0.1";
|
||||
example = "0.0.0.0";
|
||||
};
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open ports in the firewall for the server.";
|
||||
};
|
||||
@ -39,9 +36,9 @@ in
|
||||
|
||||
# implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.listen.port ];
|
||||
};
|
||||
|
||||
|
@ -1,15 +1,12 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.beesd;
|
||||
|
||||
logLevels = { emerg = 0; alert = 1; crit = 2; err = 3; warning = 4; notice = 5; info = 6; debug = 7; };
|
||||
|
||||
fsOptions = with types; {
|
||||
options.spec = mkOption {
|
||||
fsOptions = with lib.types; {
|
||||
options.spec = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
Description of how to identify the filesystem to be duplicated by this
|
||||
@ -25,8 +22,8 @@ let
|
||||
'';
|
||||
example = "LABEL=MyBulkDataDrive";
|
||||
};
|
||||
options.hashTableSizeMB = mkOption {
|
||||
type = types.addCheck types.int (n: mod n 16 == 0);
|
||||
options.hashTableSizeMB = lib.mkOption {
|
||||
type = lib.types.addCheck lib.types.int (n: mod n 16 == 0);
|
||||
default = 1024; # 1GB; default from upstream beesd script
|
||||
description = ''
|
||||
Hash table size in MB; must be a multiple of 16.
|
||||
@ -40,13 +37,13 @@ let
|
||||
will recognize only aligned duplicate blocks of 16KB.
|
||||
'';
|
||||
};
|
||||
options.verbosity = mkOption {
|
||||
type = types.enum (attrNames logLevels ++ attrValues logLevels);
|
||||
apply = v: if isString v then logLevels.${v} else v;
|
||||
options.verbosity = lib.mkOption {
|
||||
type = lib.types.enum (lib.attrNames logLevels ++ lib.attrValues logLevels);
|
||||
apply = v: if lib.isString v then logLevels.${v} else v;
|
||||
default = "info";
|
||||
description = "Log verbosity (syslog keyword/level).";
|
||||
};
|
||||
options.workDir = mkOption {
|
||||
options.workDir = lib.mkOption {
|
||||
type = str;
|
||||
default = ".beeshome";
|
||||
description = ''
|
||||
@ -54,13 +51,13 @@ let
|
||||
the hash table will be stored.
|
||||
'';
|
||||
};
|
||||
options.extraOptions = mkOption {
|
||||
options.extraOptions = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Extra command-line options passed to the daemon. See upstream bees documentation.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
[ "--thread-count" "4" ]
|
||||
'';
|
||||
};
|
||||
@ -70,11 +67,11 @@ in
|
||||
{
|
||||
|
||||
options.services.beesd = {
|
||||
filesystems = mkOption {
|
||||
type = with types; attrsOf (submodule fsOptions);
|
||||
filesystems = lib.mkOption {
|
||||
type = with lib.types; attrsOf (submodule fsOptions);
|
||||
description = "BTRFS filesystems to run block-level deduplication on.";
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
root = {
|
||||
spec = "LABEL=root";
|
||||
@ -87,8 +84,8 @@ in
|
||||
};
|
||||
};
|
||||
config = {
|
||||
systemd.services = mapAttrs'
|
||||
(name: fs: nameValuePair "beesd@${name}" {
|
||||
systemd.services = lib.mapAttrs'
|
||||
(name: fs: lib.nameValuePair "beesd@${name}" {
|
||||
description = "Block-level BTRFS deduplication for %i";
|
||||
after = [ "sysinit.target" ];
|
||||
|
||||
@ -100,11 +97,11 @@ in
|
||||
"idxSizeMB=${toString fs.hashTableSizeMB}"
|
||||
"workDir=${fs.workDir}"
|
||||
];
|
||||
configOptsStr = escapeShellArgs configOpts;
|
||||
configOptsStr = lib.escapeShellArgs configOpts;
|
||||
in
|
||||
{
|
||||
# Values from https://github.com/Zygo/bees/blob/v0.6.5/scripts/beesd@.service.in
|
||||
ExecStart = "${pkgs.bees}/bin/bees-service-wrapper run ${configOptsStr} -- --no-timestamps ${escapeShellArgs fs.extraOptions}";
|
||||
ExecStart = "${pkgs.bees}/bin/bees-service-wrapper run ${configOptsStr} -- --no-timestamps ${lib.escapeShellArgs fs.extraOptions}";
|
||||
ExecStopPost = "${pkgs.bees}/bin/bees-service-wrapper cleanup ${configOptsStr}";
|
||||
CPUAccounting = true;
|
||||
CPUSchedulingPolicy = "batch";
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
gunicorn = pkgs.python3Packages.gunicorn;
|
||||
bepasty = pkgs.bepasty;
|
||||
@ -13,20 +11,20 @@ let
|
||||
in
|
||||
{
|
||||
options.services.bepasty = {
|
||||
enable = mkEnableOption "bepasty, a binary pastebin server";
|
||||
enable = lib.mkEnableOption "bepasty, a binary pastebin server";
|
||||
|
||||
servers = mkOption {
|
||||
servers = lib.mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
configure a number of bepasty servers which will be started with
|
||||
gunicorn.
|
||||
'';
|
||||
type = with types ; attrsOf (submodule ({ config, ... } : {
|
||||
type = with lib.types ; attrsOf (submodule ({ config, ... } : {
|
||||
|
||||
options = {
|
||||
|
||||
bind = mkOption {
|
||||
type = types.str;
|
||||
bind = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Bind address to be used for this server.
|
||||
'';
|
||||
@ -34,16 +32,16 @@ in
|
||||
default = "127.0.0.1:8000";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Path to the directory where the pastes will be saved to
|
||||
'';
|
||||
default = default_home+"/data";
|
||||
};
|
||||
|
||||
defaultPermissions = mkOption {
|
||||
type = types.str;
|
||||
defaultPermissions = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
default permissions for all unauthenticated accesses.
|
||||
'';
|
||||
@ -51,8 +49,8 @@ in
|
||||
default = "read";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
Extra configuration for bepasty server to be appended on the
|
||||
configuration.
|
||||
@ -68,8 +66,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
secretKey = mkOption {
|
||||
type = types.str;
|
||||
secretKey = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
server secret for safe session cookies, must be set.
|
||||
|
||||
@ -81,8 +79,8 @@ in
|
||||
default = "";
|
||||
};
|
||||
|
||||
secretKeyFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
secretKeyFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
A file that contains the server secret for safe session cookies, must be set.
|
||||
@ -94,8 +92,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
workDir = mkOption {
|
||||
type = types.str;
|
||||
workDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Path to the working directory (used for config and pidfile).
|
||||
Defaults to the users home directory.
|
||||
@ -105,7 +103,7 @@ in
|
||||
|
||||
};
|
||||
config = {
|
||||
secretKeyFile = mkDefault (
|
||||
secretKeyFile = lib.mkDefault (
|
||||
if config.secretKey != ""
|
||||
then toString (pkgs.writeTextFile {
|
||||
name = "bepasty-secret-key";
|
||||
@ -118,13 +116,13 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ bepasty ];
|
||||
|
||||
# creates gunicorn systemd service for each configured server
|
||||
systemd.services = mapAttrs' (name: server:
|
||||
nameValuePair ("bepasty-server-${name}-gunicorn")
|
||||
systemd.services = lib.mapAttrs' (name: server:
|
||||
lib.nameValuePair ("bepasty-server-${name}-gunicorn")
|
||||
({
|
||||
description = "Bepasty Server ${name}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.calibre-server;
|
||||
@ -9,21 +6,21 @@ let
|
||||
documentationLink = "https://manual.calibre-ebook.com";
|
||||
generatedDocumentationLink = documentationLink + "/generated/en/calibre-server.html";
|
||||
|
||||
execFlags = (concatStringsSep " "
|
||||
(mapAttrsToList (k: v: "${k} ${toString v}") (filterAttrs (name: value: value != null) {
|
||||
execFlags = (lib.concatStringsSep " "
|
||||
(lib.mapAttrsToList (k: v: "${k} ${toString v}") (lib.filterAttrs (name: value: value != null) {
|
||||
"--listen-on" = cfg.host;
|
||||
"--port" = cfg.port;
|
||||
"--auth-mode" = cfg.auth.mode;
|
||||
"--userdb" = cfg.auth.userDb;
|
||||
}) ++ [(optionalString (cfg.auth.enable == true) "--enable-auth")])
|
||||
}) ++ [(lib.optionalString (cfg.auth.enable == true) "--enable-auth")])
|
||||
);
|
||||
in
|
||||
|
||||
{
|
||||
imports = [
|
||||
(mkChangedOptionModule [ "services" "calibre-server" "libraryDir" ] [ "services" "calibre-server" "libraries" ]
|
||||
(lib.mkChangedOptionModule [ "services" "calibre-server" "libraryDir" ] [ "services" "calibre-server" "libraries" ]
|
||||
(config:
|
||||
let libraryDir = getAttrFromPath [ "services" "calibre-server" "libraryDir" ] config;
|
||||
let libraryDir = lib.getAttrFromPath [ "services" "calibre-server" "libraryDir" ] config;
|
||||
in [ libraryDir ]
|
||||
)
|
||||
)
|
||||
@ -32,11 +29,11 @@ in
|
||||
options = {
|
||||
services.calibre-server = {
|
||||
|
||||
enable = mkEnableOption "calibre-server (e-book software)";
|
||||
enable = lib.mkEnableOption "calibre-server (e-book software)";
|
||||
package = lib.mkPackageOption pkgs "calibre" { };
|
||||
|
||||
libraries = mkOption {
|
||||
type = types.listOf types.path;
|
||||
libraries = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [ "/var/lib/calibre-server" ];
|
||||
description = ''
|
||||
Make sure each library path is initialized before service startup.
|
||||
@ -45,20 +42,20 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "calibre-server";
|
||||
description = "The user under which calibre-server runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "calibre-server";
|
||||
description = "The group under which calibre-server runs.";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0.0.0.0";
|
||||
example = "::1";
|
||||
description = ''
|
||||
@ -67,9 +64,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
default = 8080;
|
||||
type = types.port;
|
||||
type = lib.types.port;
|
||||
description = ''
|
||||
The port on which to listen for connections.
|
||||
See the [calibre-server documentation](${generatedDocumentationLink}#cmdoption-calibre-server-port) for details.
|
||||
@ -77,8 +74,8 @@ in
|
||||
};
|
||||
|
||||
auth = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Password based authentication to access the server.
|
||||
@ -86,8 +83,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
mode = mkOption {
|
||||
type = types.enum [ "auto" "basic" "digest" ];
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.enum [ "auto" "basic" "digest" ];
|
||||
default = "auto";
|
||||
description = ''
|
||||
Choose the type of authentication used.
|
||||
@ -96,9 +93,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
userDb = mkOption {
|
||||
userDb = lib.mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
description = ''
|
||||
Choose users database file to use for authentication.
|
||||
Make sure users database file is initialized before service startup.
|
||||
@ -109,7 +106,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.services.calibre-server = {
|
||||
description = "Calibre Server";
|
||||
@ -125,7 +122,7 @@ in
|
||||
|
||||
environment.systemPackages = [ pkgs.calibre ];
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "calibre-server") {
|
||||
users.users = lib.optionalAttrs (cfg.user == "calibre-server") {
|
||||
calibre-server = {
|
||||
home = "/var/lib/calibre-server";
|
||||
createHome = true;
|
||||
@ -134,7 +131,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == "calibre-server") {
|
||||
users.groups = lib.optionalAttrs (cfg.group == "calibre-server") {
|
||||
calibre-server = {
|
||||
gid = config.ids.gids.calibre-server;
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.canto-daemon;
|
||||
@ -13,8 +10,8 @@ in {
|
||||
options = {
|
||||
|
||||
services.canto-daemon = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the canto RSS daemon.";
|
||||
};
|
||||
@ -24,7 +21,7 @@ in {
|
||||
|
||||
##### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.user.services.canto-daemon = {
|
||||
description = "Canto RSS Daemon";
|
||||
|
@ -1,50 +1,47 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.cfdyndns;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule
|
||||
(lib.mkRemovedOptionModule
|
||||
[ "services" "cfdyndns" "apikey" ]
|
||||
"Use services.cfdyndns.apikeyFile instead.")
|
||||
];
|
||||
|
||||
options = {
|
||||
services.cfdyndns = {
|
||||
enable = mkEnableOption "Cloudflare Dynamic DNS Client";
|
||||
enable = lib.mkEnableOption "Cloudflare Dynamic DNS Client";
|
||||
|
||||
email = mkOption {
|
||||
type = types.str;
|
||||
email = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The email address to use to authenticate to CloudFlare.
|
||||
'';
|
||||
};
|
||||
|
||||
apiTokenFile = mkOption {
|
||||
apiTokenFile = lib.mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
The path to a file containing the API Token
|
||||
used to authenticate with CloudFlare.
|
||||
'';
|
||||
};
|
||||
|
||||
apikeyFile = mkOption {
|
||||
apikeyFile = lib.mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
The path to a file containing the API Key
|
||||
used to authenticate with CloudFlare.
|
||||
'';
|
||||
};
|
||||
|
||||
records = mkOption {
|
||||
records = lib.mkOption {
|
||||
default = [];
|
||||
example = [ "host.tld" ];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
The records to update in CloudFlare.
|
||||
'';
|
||||
@ -52,7 +49,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.cfdyndns = {
|
||||
description = "CloudFlare Dynamic DNS Client";
|
||||
after = [ "network.target" ];
|
||||
@ -64,14 +61,14 @@ in
|
||||
DynamicUser = true;
|
||||
};
|
||||
environment = {
|
||||
CLOUDFLARE_RECORDS="${concatStringsSep "," cfg.records}";
|
||||
CLOUDFLARE_RECORDS="${lib.concatStringsSep "," cfg.records}";
|
||||
};
|
||||
script = ''
|
||||
${optionalString (cfg.apikeyFile != null) ''
|
||||
export CLOUDFLARE_APIKEY="$(cat ${escapeShellArg cfg.apikeyFile})"
|
||||
${lib.optionalString (cfg.apikeyFile != null) ''
|
||||
export CLOUDFLARE_APIKEY="$(cat ${lib.escapeShellArg cfg.apikeyFile})"
|
||||
export CLOUDFLARE_EMAIL="${cfg.email}"
|
||||
''}
|
||||
${optionalString (cfg.apiTokenFile != null) ''
|
||||
${lib.optionalString (cfg.apiTokenFile != null) ''
|
||||
export CLOUDFLARE_APITOKEN=$(${pkgs.systemd}/bin/systemd-creds cat CLOUDFLARE_APITOKEN_FILE)
|
||||
''}
|
||||
${pkgs.cfdyndns}/bin/cfdyndns
|
||||
|
@ -1,25 +1,22 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.cgminer;
|
||||
|
||||
convType = with builtins;
|
||||
v: if isBool v then boolToString v else toString v;
|
||||
v: if lib.isBool v then lib.boolToString v else toString v;
|
||||
mergedHwConfig =
|
||||
mapAttrsToList (n: v: ''"${n}": "${(concatStringsSep "," (map convType v))}"'')
|
||||
(foldAttrs (n: a: [n] ++ a) [] cfg.hardware);
|
||||
lib.mapAttrsToList (n: v: ''"${n}": "${(lib.concatStringsSep "," (map convType v))}"'')
|
||||
(lib.foldAttrs (n: a: [n] ++ a) [] cfg.hardware);
|
||||
mergedConfig = with builtins;
|
||||
mapAttrsToList (n: v: ''"${n}": ${if isBool v then convType v else ''"${convType v}"''}'')
|
||||
lib.mapAttrsToList (n: v: ''"${n}": ${if lib.isBool v then convType v else ''"${convType v}"''}'')
|
||||
cfg.config;
|
||||
|
||||
cgminerConfig = pkgs.writeText "cgminer.conf" ''
|
||||
{
|
||||
${concatStringsSep ",\n" mergedHwConfig},
|
||||
${concatStringsSep ",\n" mergedConfig},
|
||||
${lib.concatStringsSep ",\n" mergedHwConfig},
|
||||
${lib.concatStringsSep ",\n" mergedConfig},
|
||||
"pools": [
|
||||
${concatStringsSep ",\n"
|
||||
${lib.concatStringsSep ",\n"
|
||||
(map (v: ''{"url": "${v.url}", "user": "${v.user}", "pass": "${v.pass}"}'')
|
||||
cfg.pools)}]
|
||||
}
|
||||
@ -31,19 +28,19 @@ in
|
||||
|
||||
services.cgminer = {
|
||||
|
||||
enable = mkEnableOption "cgminer, an ASIC/FPGA/GPU miner for bitcoin and litecoin";
|
||||
enable = lib.mkEnableOption "cgminer, an ASIC/FPGA/GPU miner for bitcoin and litecoin";
|
||||
|
||||
package = mkPackageOption pkgs "cgminer" { };
|
||||
package = lib.mkPackageOption pkgs "cgminer" { };
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "cgminer";
|
||||
description = "User account under which cgminer runs";
|
||||
};
|
||||
|
||||
pools = mkOption {
|
||||
pools = lib.mkOption {
|
||||
default = []; # Run benchmark
|
||||
type = types.listOf (types.attrsOf types.str);
|
||||
type = lib.types.listOf (lib.types.attrsOf lib.types.str);
|
||||
description = "List of pools where to mine";
|
||||
example = [{
|
||||
url = "http://p2pool.org:9332";
|
||||
@ -52,9 +49,9 @@ in
|
||||
}];
|
||||
};
|
||||
|
||||
hardware = mkOption {
|
||||
hardware = lib.mkOption {
|
||||
default = []; # Run without options
|
||||
type = types.listOf (types.attrsOf (types.either types.str types.int));
|
||||
type = lib.types.listOf (lib.types.attrsOf (lib.types.either lib.types.str lib.types.int));
|
||||
description= "List of config options for every GPU";
|
||||
example = [
|
||||
{
|
||||
@ -79,9 +76,9 @@ in
|
||||
}];
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
config = lib.mkOption {
|
||||
default = {};
|
||||
type = types.attrsOf (types.either types.bool types.int);
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.bool lib.types.int);
|
||||
description = "Additional config";
|
||||
example = {
|
||||
auto-fan = true;
|
||||
@ -101,16 +98,16 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.cgminer.enable {
|
||||
config = lib.mkIf config.services.cgminer.enable {
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "cgminer") {
|
||||
users.users = lib.optionalAttrs (cfg.user == "cgminer") {
|
||||
cgminer = {
|
||||
isSystemUser = true;
|
||||
group = "cgminer";
|
||||
description = "Cgminer user";
|
||||
};
|
||||
};
|
||||
users.groups = optionalAttrs (cfg.user == "cgminer") {
|
||||
users.groups = lib.optionalAttrs (cfg.user == "cgminer") {
|
||||
cgminer = {};
|
||||
};
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.clipcat;
|
||||
in {
|
||||
|
||||
options.services.clipcat= {
|
||||
enable = mkEnableOption "Clipcat clipboard daemon";
|
||||
enable = lib.mkEnableOption "Clipcat clipboard daemon";
|
||||
|
||||
package = mkPackageOption pkgs "clipcat" { };
|
||||
package = lib.mkPackageOption pkgs "clipcat" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.user.services.clipcat = {
|
||||
enable = true;
|
||||
description = "clipcat daemon";
|
||||
|
@ -1,18 +1,15 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.clipmenu;
|
||||
in {
|
||||
|
||||
options.services.clipmenu = {
|
||||
enable = mkEnableOption "clipmenu, the clipboard management daemon";
|
||||
enable = lib.mkEnableOption "clipmenu, the clipboard management daemon";
|
||||
|
||||
package = mkPackageOption pkgs "clipmenu" { };
|
||||
package = lib.mkPackageOption pkgs "clipmenu" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.user.services.clipmenu = {
|
||||
enable = true;
|
||||
description = "Clipboard management daemon";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.confd;
|
||||
|
||||
@ -9,62 +6,62 @@ let
|
||||
backend = "${cfg.backend}"
|
||||
confdir = "${cfg.confDir}"
|
||||
interval = ${toString cfg.interval}
|
||||
nodes = [ ${concatMapStringsSep "," (s: ''"${s}"'') cfg.nodes}, ]
|
||||
nodes = [ ${lib.concatMapStringsSep "," (s: ''"${s}"'') cfg.nodes}, ]
|
||||
prefix = "${cfg.prefix}"
|
||||
log-level = "${cfg.logLevel}"
|
||||
watch = ${boolToString cfg.watch}
|
||||
watch = ${lib.boolToString cfg.watch}
|
||||
'';
|
||||
|
||||
in {
|
||||
options.services.confd = {
|
||||
enable = mkEnableOption "confd, a service to manage local application configuration files using templates and data from etcd/consul/redis/zookeeper";
|
||||
enable = lib.mkEnableOption "confd, a service to manage local application configuration files using templates and data from etcd/consul/redis/zookeeper";
|
||||
|
||||
backend = mkOption {
|
||||
backend = lib.mkOption {
|
||||
description = "Confd config storage backend to use.";
|
||||
default = "etcd";
|
||||
type = types.enum ["etcd" "consul" "redis" "zookeeper"];
|
||||
type = lib.types.enum ["etcd" "consul" "redis" "zookeeper"];
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
interval = lib.mkOption {
|
||||
description = "Confd check interval.";
|
||||
default = 10;
|
||||
type = types.int;
|
||||
type = lib.types.int;
|
||||
};
|
||||
|
||||
nodes = mkOption {
|
||||
nodes = lib.mkOption {
|
||||
description = "Confd list of nodes to connect to.";
|
||||
default = [ "http://127.0.0.1:2379" ];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
};
|
||||
|
||||
watch = mkOption {
|
||||
watch = lib.mkOption {
|
||||
description = "Confd, whether to watch etcd config for changes.";
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
prefix = mkOption {
|
||||
prefix = lib.mkOption {
|
||||
description = "The string to prefix to keys.";
|
||||
default = "/";
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
logLevel = lib.mkOption {
|
||||
description = "Confd log level.";
|
||||
default = "info";
|
||||
type = types.enum ["info" "debug"];
|
||||
type = lib.types.enum ["info" "debug"];
|
||||
};
|
||||
|
||||
confDir = mkOption {
|
||||
confDir = lib.mkOption {
|
||||
description = "The path to the confd configs.";
|
||||
default = "/etc/confd";
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "confd" { };
|
||||
package = lib.mkPackageOption pkgs "confd" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.confd = {
|
||||
description = "Confd Service.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
@ -80,6 +77,6 @@ in {
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
services.etcd.enable = mkIf (cfg.backend == "etcd") (mkDefault true);
|
||||
services.etcd.enable = lib.mkIf (cfg.backend == "etcd") (lib.mkDefault true);
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.cpuminer-cryptonight;
|
||||
|
||||
@ -20,28 +17,28 @@ in
|
||||
options = {
|
||||
|
||||
services.cpuminer-cryptonight = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the cpuminer cryptonight miner.
|
||||
'';
|
||||
};
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "URL of mining server";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Username for mining server";
|
||||
};
|
||||
pass = mkOption {
|
||||
type = types.str;
|
||||
pass = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "x";
|
||||
description = "Password for mining server";
|
||||
};
|
||||
threads = mkOption {
|
||||
type = types.int;
|
||||
threads = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 0;
|
||||
description = "Number of miner threads, defaults to available processors";
|
||||
};
|
||||
@ -49,7 +46,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
config = mkIf config.services.cpuminer-cryptonight.enable {
|
||||
config = lib.mkIf config.services.cpuminer-cryptonight.enable {
|
||||
|
||||
systemd.services.cpuminer-cryptonight = {
|
||||
description = "Cryptonight cpuminer";
|
||||
|
@ -1,18 +1,15 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.devmon;
|
||||
|
||||
in {
|
||||
options = {
|
||||
services.devmon = {
|
||||
enable = mkEnableOption "devmon, an automatic device mounting daemon";
|
||||
enable = lib.mkEnableOption "devmon, an automatic device mounting daemon";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.user.services.devmon = {
|
||||
description = "devmon automatic device mounting daemon";
|
||||
wantedBy = [ "default.target" ];
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user