Merge master into haskell-updates

This commit is contained in:
github-actions[bot] 2024-08-31 00:15:04 +00:00 committed by GitHub
commit 179b0a961b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
347 changed files with 5301 additions and 4136 deletions

View File

@ -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.

View File

@ -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

View File

@ -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$' "$@"

View File

@ -0,0 +1,4 @@
{
imports = [ ./importApply.nix ];
disabledModules = [ ./importApply-function.nix ];
}

View File

@ -0,0 +1,5 @@
{ foo }:
{ lib, config, ... }:
{
value = foo;
}

View File

@ -0,0 +1,5 @@
{ lib, ... }:
{
options.value = lib.mkOption { default = 1; };
imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ];
}

View File

@ -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";

View File

@ -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";

View File

@ -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.

View File

@ -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)

View File

@ -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)}
'';
};

View File

@ -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.

View File

@ -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;
};
}

View File

@ -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" ];
};
}

View File

@ -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}" = { };
};

View File

@ -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" ];
};
}

View File

@ -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"

View File

@ -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 ];
};
}

View File

@ -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
'';

View File

@ -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 ];
};
}

View File

@ -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.";
};

View File

@ -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 ];

View File

@ -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 ];

View File

@ -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 ];
};

View File

@ -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.

View File

@ -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 ];
};
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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" ];

View File

@ -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" ];

View File

@ -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")
];
};

View File

@ -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" ];

View File

@ -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" ];

View File

@ -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
];

View File

@ -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 ];

View File

@ -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 ];

View File

@ -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 ];

View File

@ -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"
'';

View File

@ -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 ];

View File

@ -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" ];

View File

@ -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" ];

View File

@ -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)

View File

@ -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 = ''

View File

@ -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 ];
};

View File

@ -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 ];
};
}

View File

@ -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 ];
};
}

View File

@ -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 ];
};

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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 ];

View File

@ -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}";

View File

@ -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";
};
};

View File

@ -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";

View File

@ -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" ];

View File

@ -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 ];
}

View File

@ -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.

View File

@ -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 ];
};

View File

@ -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;

View File

@ -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";

View File

@ -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";

View File

@ -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;

View File

@ -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" ]; };
};
}

View File

@ -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 ];

View File

@ -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 = [

View File

@ -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 ];
};

View File

@ -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";

View File

@ -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;

View File

@ -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" ];
})

View File

@ -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";
};

View File

@ -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 ];
};
}

View File

@ -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;

View 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 ];
}

View File

@ -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;

View File

@ -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/" ];

View File

@ -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 ];
}

View File

@ -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 ];
}

View File

@ -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 ];
};
}

View File

@ -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 ];
}

View File

@ -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

View File

@ -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 ];
};
}

View File

@ -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} = {

View File

@ -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;

View File

@ -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";

View File

@ -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
'');

View File

@ -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";
};
};

View File

@ -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 = {};
};
};

View File

@ -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}"
'';

View File

@ -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 ];
};

View File

@ -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";

View File

@ -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" ];

View File

@ -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;
};

View File

@ -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";

View File

@ -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

View File

@ -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 = {};
};

View File

@ -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";

View File

@ -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";

View File

@ -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);
};
}

View File

@ -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";

View File

@ -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