Merge master into haskell-updates

This commit is contained in:
github-actions[bot] 2024-09-16 00:16:32 +00:00 committed by GitHub
commit 4bb582676a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
766 changed files with 7798 additions and 7148 deletions

View File

@ -0,0 +1,29 @@
# `haredo` {#haredo-hook}
This hook uses [the `haredo` command runner](https://sr.ht/~autumnull/haredo/) to build, check, and install the package. It overrides `buildPhase`, `checkPhase`, and `installPhase` by default.
The hook builds its targets in parallel if [`config.enableParallelBuilding`](#var-stdenv-enableParallelBuilding) is set to `true`.
## `buildPhase` {#haredo-hook-buildPhase}
This phase attempts to build the default target.
[]{#haredo-hook-haredoBuildTargets} Targets can be explicitly set by adding a string to the `haredoBuildTargets` list.
[]{#haredo-hook-dontUseHaredoBuild} This behavior can be disabled by setting `dontUseHaredoBuild` to `true`.
## `checkPhase` {#haredo-hook-checkPhase}
This phase searches for the `check.do` or `test.do` targets, running them if they exist.
[]{#haredo-hook-haredoCheckTargets} Targets can be explicitly set by adding a string to the `haredoCheckTargets` list.
[]{#haredo-hook-dontUseHaredoCheck} This behavior can be disabled by setting `dontUseHaredoCheck` to `true`.
## `installPhase` {#haredo-hook-installPhase}
This phase attempts to build the `install.do` target, if it exists.
[]{#haredo-hook-haredoInstallTargets} Targets can be explicitly set by adding a string to the `haredoInstallTargets` list.
[]{#haredo-hook-dontUseHaredoInstall} This behavior can be disabled by setting `dontUseHaredoInstall` to `true`.

View File

@ -15,6 +15,7 @@ cmake.section.md
gdk-pixbuf.section.md
ghc.section.md
gnome.section.md
haredo.section.md
installShellFiles.section.md
libiconv.section.md
libxml2.section.md
@ -25,6 +26,7 @@ patch-rc-path-hooks.section.md
perl.section.md
pkg-config.section.md
postgresql-test-hook.section.md
premake.section.md
python.section.md
scons.section.md
tetex-tex-live.section.md

View File

@ -0,0 +1,7 @@
# Premake {#premake-hook}
This setup hook attempts to configure the package using [the Premake build configuration system](https://premake.github.io/). It overrides the `configurePhase` by default, if none exists.
[]{#premake-hook-premakefile} The Premakefile to use can be specified by setting `premakefile` in the derivation.
[]{#premake-hook-premakeFlagsArray} The flags passed to Premake can be configured by adding strings to the `premakeFlags` list.

View File

@ -3277,7 +3277,10 @@
github = "callumio";
githubId = 16057677;
name = "Callum Leslie";
keys = [ { fingerprint = "BC82 4BB5 1656 D144 285E A0EC D382 C4AF EECE AA90"; } ];
keys = [
{ fingerprint = "BC82 4BB5 1656 D144 285E A0EC D382 C4AF EECE AA90"; }
{ fingerprint = "890B 06FB 209A 3E44 9491 C028 03B0 1F42 7831 BCFD"; }
];
};
calvertvl = {
email = "calvertvl@gmail.com";
@ -4556,6 +4559,12 @@
githubId = 24708079;
name = "Dan Eads";
};
danerieber = {
email = "danerieber@gmail.com";
github = "danerieber";
githubId = 6487079;
name = "Dane Rieber";
};
danid3v = {
email = "sch220233@spengergasse.at";
github = "DaniD3v";
@ -10880,13 +10889,6 @@
githubId = 8211181;
name = "Kevin Kandlbinder";
};
kfears = {
email = "kfearsoff@gmail.com";
github = "KFearsoff";
githubId = 66781795;
matrix = "@kfears:matrix.org";
name = "KFears";
};
kfollesdal = {
email = "kfollesdal@gmail.com";
github = "kfollesdal";
@ -12129,6 +12131,11 @@
githubId = 4969294;
name = "Louis Tim Larsen";
};
louis-thevenet = {
name = "Louis Thevenet";
github = "louis-thevenet";
githubId = 55986107;
};
lovek323 = {
email = "jason@oconal.id.au";
github = "lovek323";
@ -17234,6 +17241,12 @@
githubId = 131856;
name = "Arnout Engelen";
};
racci = {
name = "James Draycott";
email = "me@racci.dev";
github = "DaRacci";
githubId = 90304606;
};
raehik = {
email = "thefirstmuffinman@gmail.com";
github = "raehik";

View File

@ -201,6 +201,10 @@ def fileToSRI(p: Path):
_SKIP_RE = re.compile("(generated by)|(do not edit)", re.IGNORECASE)
_IGNORE = frozenset({
"gemset.nix",
"yarn.nix",
})
if __name__ == "__main__":
from sys import argv
@ -239,7 +243,7 @@ if __name__ == "__main__":
logger.info("Recursing into directory")
for q in p.glob("**/*.nix"):
if q.is_file():
if q.name == "yarn.nix" or q.name.find("generated") != -1:
if q.name in _IGNORE or q.name.find("generated") != -1:
logger.info("File looks autogenerated, skipping!")
continue

View File

@ -496,6 +496,12 @@ Use the following commands:
Retype new password: ***
```
If you have a user account declared in your `configuration.nix` and plan to log in using this user, set a password before rebooting, e.g. for the `alice` user:
```ShellSession
# nixos-enter --root /mnt -c 'passwd alice'
```
::: {.note}
For unattended installations, it is possible to use
`nixos-install --no-root-passwd` in order to disable the password
@ -515,15 +521,13 @@ Use the following commands:
menu. This allows you to easily roll back to a previous
configuration if something goes wrong.
You should log in and change the `root` password with `passwd`.
Use your declared user account to log in.
If you didnt declare one, you should still be able to log in using the `root` user.
You'll probably want to create some user accounts as well, which can
be done with `useradd`:
```ShellSession
$ useradd -c 'Eelco Dolstra' -m eelco
$ passwd eelco
```
::: {.note}
Some graphical display managers such as SDDM do not allow `root` login by default, so you might need to switch to TTY.
Refer to [](#sec-user-management) for details on declaring user accounts.
:::
You may also want to install some software. This will be covered in
[](#sec-package-management).

View File

@ -243,7 +243,7 @@
- `forgejo` and `forgejo-lts` no longer support the opt-in feature [PAM (Pluggable Authentication Module)](https://forgejo.org/docs/latest/user/authentication/#pam-pluggable-authentication-module).
- `gitea` no longer supports the opt-in feature [PAM (Pluggable Authentication Module)][https://docs.gitea.com/usage/authentication#pam-pluggable-authentication-module].
- `gitea` no longer supports the opt-in feature [PAM (Pluggable Authentication Module)](https://docs.gitea.com/usage/authentication#pam-pluggable-authentication-module).
- `services.ddclient.use` has been deprecated: `ddclient` now supports separate IPv4 and IPv6 configuration. Use `services.ddclient.usev4` and `services.ddclient.usev6` instead.

View File

@ -1,10 +1,6 @@
# This module contains the basic configuration for building a NixOS
# installation CD.
{ config, lib, options, pkgs, ... }:
with lib;
{
imports =
[ ./iso-image.nix
@ -32,8 +28,8 @@ with lib;
# An installation media cannot tolerate a host config defined file
# system layout on a fresh machine, before it has been formatted.
swapDevices = mkImageMediaOverride [ ];
fileSystems = mkImageMediaOverride config.lib.isoFileSystems;
swapDevices = lib.mkImageMediaOverride [ ];
fileSystems = lib.mkImageMediaOverride config.lib.isoFileSystems;
boot.postBootCommands = ''
for o in $(</proc/cmdline); do

View File

@ -1,10 +1,6 @@
# This module contains the basic configuration for building a graphical NixOS
# installation CD.
{ lib, pkgs, ... }:
with lib;
{
imports = [ ./installation-cd-base.nix ];
@ -26,7 +22,7 @@ with lib;
# Provide networkmanager for easy wireless configuration.
networking.networkmanager.enable = true;
networking.wireless.enable = mkImageMediaOverride false;
networking.wireless.enable = lib.mkImageMediaOverride false;
# KDE complains if power management is disabled (to be precise, if
# there is no power management backend such as upower).

View File

@ -1,11 +1,8 @@
# List all devices which are detected by nixos-generate-config.
# Common devices are enabled by default.
{ lib, ... }:
with lib;
{
config = mkDefault {
config = lib.mkDefault {
# Common firmware, i.e. for wifi cards
hardware.enableRedistributableFirmware = true;
};

View File

@ -1,19 +1,16 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.nixpkgs.flake;
in
{
options.nixpkgs.flake = {
source = mkOption {
source = lib.mkOption {
# In newer Nix versions, particularly with lazy trees, outPath of
# flakes becomes a Nix-language path object. We deliberately allow this
# to gracefully come through the interface in discussion with @roberth.
#
# See: https://github.com/NixOS/nixpkgs/pull/278522#discussion_r1460292639
type = types.nullOr (types.either types.str types.path);
type = lib.types.nullOr (lib.types.either lib.types.str lib.types.path);
default = null;
defaultText = "if (using nixpkgsFlake.lib.nixosSystem) then self.outPath else null";
@ -34,8 +31,8 @@ in
'';
};
setNixPath = mkOption {
type = types.bool;
setNixPath = lib.mkOption {
type = lib.types.bool;
default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
@ -54,8 +51,8 @@ in
'';
};
setFlakeRegistry = mkOption {
type = types.bool;
setFlakeRegistry = lib.mkOption {
type = lib.types.bool;
default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
@ -75,7 +72,7 @@ in
};
};
config = mkIf (cfg.source != null) (mkMerge [
config = lib.mkIf (cfg.source != null) (lib.mkMerge [
{
assertions = [
{
@ -87,19 +84,19 @@ in
}
];
}
(mkIf cfg.setFlakeRegistry {
nix.registry.nixpkgs.to = mkDefault {
(lib.mkIf cfg.setFlakeRegistry {
nix.registry.nixpkgs.to = lib.mkDefault {
type = "path";
path = cfg.source;
};
})
(mkIf cfg.setNixPath {
(lib.mkIf cfg.setNixPath {
# N.B. This does not include nixos-config in NIX_PATH unlike modules/config/nix-channel.nix
# because we would need some kind of evil shim taking the *calling* flake's self path,
# perhaps, to ever make that work (in order to know where the Nix expr for the system came
# from and how to call it).
nix.nixPath = mkDefault ([ "nixpkgs=flake:nixpkgs" ]
++ optional config.nix.channel.enable "/nix/var/nix/profiles/per-user/root/channels");
nix.nixPath = lib.mkDefault ([ "nixpkgs=flake:nixpkgs" ]
++ lib.optional config.nix.channel.enable "/nix/var/nix/profiles/per-user/root/channels");
})
]);
}

View File

@ -1,7 +1,4 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.nixpkgs;
opt = options.nixpkgs;
@ -19,19 +16,19 @@ let
lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; };
in
recursiveUpdate lhs rhs //
optionalAttrs (lhs ? packageOverrides) {
lib.recursiveUpdate lhs rhs //
lib.optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs //
optCall (attrByPath [ "packageOverrides" ] { } rhs) pkgs;
optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
} //
optionalAttrs (lhs ? perlPackageOverrides) {
lib.optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs //
optCall (attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
};
configType = mkOptionType {
configType = lib.mkOptionType {
name = "nixpkgs-config";
description = "nixpkgs config";
check = x:
@ -39,34 +36,34 @@ let
if c x then true
else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: foldr (def: mergeConfig def.value) {};
merge = args: lib.foldr (def: mergeConfig def.value) {};
};
overlayType = mkOptionType {
overlayType = lib.mkOptionType {
name = "nixpkgs-overlay";
description = "nixpkgs overlay";
check = lib.isFunction;
merge = lib.mergeOneOption;
};
pkgsType = types.pkgs // {
pkgsType = lib.types.pkgs // {
# This type is only used by itself, so let's elaborate the description a bit
# for the purpose of documentation.
description = "An evaluation of Nixpkgs; the top level attribute set of packages";
};
hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority;
hasBuildPlatform = opt.buildPlatform.highestPrio < (lib.mkOptionDefault {}).priority;
hasHostPlatform = opt.hostPlatform.isDefined;
hasPlatform = hasHostPlatform || hasBuildPlatform;
# Context for messages
hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}";
hostPlatformLine = lib.optionalString hasHostPlatform "${lib.showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = lib.optionalString hasBuildPlatform "${lib.showOptionWithDefLocs opt.buildPlatform}";
legacyOptionsDefined =
optional (opt.localSystem.highestPrio < (mkDefault {}).priority) opt.system
++ optional (opt.localSystem.highestPrio < (mkOptionDefault {}).priority) opt.localSystem
++ optional (opt.crossSystem.highestPrio < (mkOptionDefault {}).priority) opt.crossSystem
lib.optional (opt.localSystem.highestPrio < (lib.mkDefault {}).priority) opt.system
++ lib.optional (opt.localSystem.highestPrio < (lib.mkOptionDefault {}).priority) opt.localSystem
++ lib.optional (opt.crossSystem.highestPrio < (lib.mkOptionDefault {}).priority) opt.crossSystem
;
defaultPkgs =
@ -99,19 +96,19 @@ in
imports = [
./assertions.nix
./meta.nix
(mkRemovedOptionModule [ "nixpkgs" "initialSystem" ] "The NixOS options `nesting.clone` and `nesting.children` have been deleted, and replaced with named specialisation. Therefore `nixpgks.initialSystem` has no effect anymore.")
(lib.mkRemovedOptionModule [ "nixpkgs" "initialSystem" ] "The NixOS options `nesting.clone` and `nesting.children` have been deleted, and replaced with named specialisation. Therefore `nixpgks.initialSystem` has no effect lib.anymore.")
];
options.nixpkgs = {
pkgs = mkOption {
defaultText = literalExpression ''
pkgs = lib.mkOption {
defaultText = lib.literalExpression ''
import "''${nixos}/.." {
inherit (cfg) config overlays localSystem crossSystem;
}
'';
type = pkgsType;
example = literalExpression "import <nixpkgs> {}";
example = lib.literalExpression "import <nixpkgs> {}";
description = ''
If set, the pkgs argument to all NixOS modules is the value of
this option, extended with `nixpkgs.overlays`, if
@ -145,9 +142,9 @@ in
'';
};
config = mkOption {
config = lib.mkOption {
default = {};
example = literalExpression
example = lib.literalExpression
''
{ allowBroken = true; allowUnfree = true; }
'';
@ -160,9 +157,9 @@ in
'';
};
overlays = mkOption {
overlays = lib.mkOption {
default = [];
example = literalExpression
example = lib.literalExpression
''
[
(self: super: {
@ -173,7 +170,7 @@ in
})
]
'';
type = types.listOf overlayType;
type = lib.types.listOf overlayType;
description = ''
List of overlays to apply to Nixpkgs.
This option allows modifying the Nixpkgs package set accessed through the `pkgs` module argument.
@ -184,13 +181,13 @@ in
'';
};
hostPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
hostPlatform = lib.mkOption {
type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
example = { system = "aarch64-linux"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib.systems.elaborate;
defaultText = literalExpression
defaultText = lib.literalExpression
''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
description = ''
Specifies the platform where the NixOS configuration will run.
@ -201,8 +198,8 @@ in
'';
};
buildPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
buildPlatform = lib.mkOption {
type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
default = cfg.hostPlatform;
example = { system = "x86_64-linux"; };
# Make sure that the final value has all fields for sake of other modules
@ -212,7 +209,7 @@ in
in if lib.systems.equals elaborated cfg.hostPlatform
then cfg.hostPlatform # make identical, so that `==` equality works; see https://github.com/NixOS/nixpkgs/issues/278001
else elaborated;
defaultText = literalExpression
defaultText = lib.literalExpression
''config.nixpkgs.hostPlatform'';
description = ''
Specifies the platform on which NixOS should be built.
@ -228,14 +225,14 @@ in
'';
};
localSystem = mkOption {
type = types.attrs; # TODO utilize lib.systems.parsedPlatform
localSystem = lib.mkOption {
type = lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
default = { inherit (cfg) system; };
example = { system = "aarch64-linux"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib.systems.elaborate;
defaultText = literalExpression
defaultText = lib.literalExpression
''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
description = ''
Systems with a recently generated `hardware-configuration.nix`
@ -262,8 +259,8 @@ in
# TODO deprecate. "crossSystem" is a nonsense identifier, because "cross"
# is a relation between at least 2 systems in the context of a
# specific build step, not a single system.
crossSystem = mkOption {
type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform
crossSystem = lib.mkOption {
type = lib.types.nullOr lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
default = null;
example = { system = "aarch64-linux"; };
description = ''
@ -283,8 +280,8 @@ in
'';
};
system = mkOption {
type = types.str;
system = lib.mkOption {
type = lib.types.str;
example = "i686-linux";
default =
if opt.hostPlatform.isDefined
@ -372,12 +369,12 @@ in
{
assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == [];
message = ''
Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}:
Your system configures nixpkgs with the platform parameter${lib.optionalString hasBuildPlatform "s"}:
${hostPlatformLine
}${buildPlatformLine
}
However, it also defines the legacy options:
${concatMapStrings showOptionWithDefLocs legacyOptionsDefined}
${lib.concatMapStrings lib.showOptionWithDefLocs legacyOptionsDefined}
For a future proof system configuration, we recommend to remove
the legacy definitions.
'';

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
concatAndSort = name: files: pkgs.runCommand name {} ''
awk 1 ${lib.escapeShellArgs files} | sed '{ /^\s*$/d; s/^\s\+//; s/\s\+$// }' | sort | uniq > $out
@ -8,16 +7,16 @@ in
{
options = {
environment.wordlist = {
enable = mkEnableOption "environment variables for lists of words";
enable = lib.mkEnableOption "environment variables for lists of words";
lists = mkOption {
type = types.attrsOf (types.nonEmptyListOf types.path);
lists = lib.mkOption {
type = lib.types.attrsOf (lib.types.nonEmptyListOf lib.types.path);
default = {
WORDLIST = [ "${pkgs.scowl}/share/dict/words.txt" ];
};
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
{
WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ];
}
@ -34,7 +33,7 @@ in
task.
'';
example = literalExpression ''
example = lib.literalExpression ''
{
WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ];
AUGMENTED_WORDLIST = [
@ -50,7 +49,7 @@ in
};
};
config = mkIf config.environment.wordlist.enable {
config = lib.mkIf config.environment.wordlist.enable {
environment.variables =
lib.mapAttrs
(name: value: "${concatAndSort "wordlist-${name}" value}")

View File

@ -1,10 +1,7 @@
{ config, lib, ... }:
with lib;
{
meta = {
maintainers = [ maintainers.joachifm ];
maintainers = [ lib.maintainers.joachifm ];
};
imports = [
@ -12,8 +9,8 @@ with lib;
];
options = {
security.allowUserNamespaces = mkOption {
type = types.bool;
security.allowUserNamespaces = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to allow creation of user namespaces.
@ -31,8 +28,8 @@ with lib;
'';
};
security.unprivilegedUsernsClone = mkOption {
type = types.bool;
security.unprivilegedUsernsClone = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
When disabled, unprivileged users will not be able to create new namespaces.
@ -41,16 +38,16 @@ with lib;
'';
};
security.protectKernelImage = mkOption {
type = types.bool;
security.protectKernelImage = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to prevent replacing the running kernel image.
'';
};
security.allowSimultaneousMultithreading = mkOption {
type = types.bool;
security.allowSimultaneousMultithreading = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to allow SMT/hyperthreading. Disabling SMT means that only
@ -68,8 +65,8 @@ with lib;
'';
};
security.forcePageTableIsolation = mkOption {
type = types.bool;
security.forcePageTableIsolation = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to force-enable the Page Table Isolation (PTI) Linux kernel
@ -80,8 +77,8 @@ with lib;
'';
};
security.virtualisation.flushL1DataCache = mkOption {
type = types.nullOr (types.enum [ "never" "cond" "always" ]);
security.virtualisation.flushL1DataCache = lib.mkOption {
type = lib.types.nullOr (lib.types.enum [ "never" "cond" "always" ]);
default = null;
description = ''
Whether the hypervisor should flush the L1 data cache before
@ -100,8 +97,8 @@ with lib;
};
};
config = mkMerge [
(mkIf (!config.security.allowUserNamespaces) {
config = lib.mkMerge [
(lib.mkIf (!config.security.allowUserNamespaces) {
# Setting the number of allowed user namespaces to 0 effectively disables
# the feature at runtime. Note that root may raise the limit again
# at any time.
@ -114,26 +111,26 @@ with lib;
];
})
(mkIf config.security.unprivilegedUsernsClone {
boot.kernel.sysctl."kernel.unprivileged_userns_clone" = mkDefault true;
(lib.mkIf config.security.unprivilegedUsernsClone {
boot.kernel.sysctl."kernel.unprivileged_userns_clone" = lib.mkDefault true;
})
(mkIf config.security.protectKernelImage {
(lib.mkIf config.security.protectKernelImage {
# Disable hibernation (allows replacing the running kernel)
boot.kernelParams = [ "nohibernate" ];
# Prevent replacing the running kernel image w/o reboot
boot.kernel.sysctl."kernel.kexec_load_disabled" = mkDefault true;
boot.kernel.sysctl."kernel.kexec_load_disabled" = lib.mkDefault true;
})
(mkIf (!config.security.allowSimultaneousMultithreading) {
(lib.mkIf (!config.security.allowSimultaneousMultithreading) {
boot.kernelParams = [ "nosmt" ];
})
(mkIf config.security.forcePageTableIsolation {
(lib.mkIf config.security.forcePageTableIsolation {
boot.kernelParams = [ "pti=on" ];
})
(mkIf (config.security.virtualisation.flushL1DataCache != null) {
(lib.mkIf (config.security.virtualisation.flushL1DataCache != null) {
boot.kernelParams = [ "kvm-intel.vmentry_l1d_flush=${config.security.virtualisation.flushL1DataCache}" ];
})
];

View File

@ -1,32 +1,28 @@
# This module provides configuration for the OATH PAM modules.
{ lib, ... }:
with lib;
{
options = {
security.pam.oath = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Enable the OATH (one-time password) PAM module.
'';
};
digits = mkOption {
type = types.enum [ 6 7 8 ];
digits = lib.mkOption {
type = lib.types.enum [ 6 7 8 ];
default = 6;
description = ''
Specify the length of the one-time password in number of
Specify the lib.length of the one-time password in number of
digits.
'';
};
window = mkOption {
type = types.int;
window = lib.mkOption {
type = lib.types.int;
default = 5;
description = ''
Specify the number of one-time passwords to check in order
@ -36,8 +32,8 @@ with lib;
'';
};
usersFile = mkOption {
type = types.path;
usersFile = lib.mkOption {
type = lib.types.path;
default = "/etc/users.oath";
description = ''
Set the path to file where the user's credentials are

View File

@ -1,15 +1,12 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.pgadmin;
_base = with types; [ int bool str ];
base = with types; oneOf ([ (listOf (oneOf _base)) (attrsOf (oneOf _base)) ] ++ _base);
_base = with lib.types; [ int bool str ];
base = with lib.types; oneOf ([ (listOf (oneOf _base)) (attrsOf (oneOf _base)) ] ++ _base);
formatAttrset = attr:
"{${concatStringsSep "\n" (mapAttrsToList (key: value: "${builtins.toJSON key}: ${formatPyValue value},") attr)}}";
"{${lib.concatStringsSep "\n" (lib.mapAttrsToList (key: value: "${builtins.toJSON key}: ${formatPyValue value},") attr)}}";
formatPyValue = value:
if builtins.isString value then builtins.toJSON value
@ -17,98 +14,98 @@ let
else if builtins.isInt value then toString value
else if builtins.isBool value then (if value then "True" else "False")
else if builtins.isAttrs value then (formatAttrset value)
else if builtins.isList value then "[${concatStringsSep "\n" (map (v: "${formatPyValue v},") value)}]"
else if builtins.isList value then "[${lib.concatStringsSep "\n" (map (v: "${formatPyValue v},") value)}]"
else throw "Unrecognized type";
formatPy = attrs:
concatStringsSep "\n" (mapAttrsToList (key: value: "${key} = ${formatPyValue value}") attrs);
lib.concatStringsSep "\n" (lib.mapAttrsToList (key: value: "${key} = ${formatPyValue value}") attrs);
pyType = with types; attrsOf (oneOf [ (attrsOf base) (listOf base) base ]);
pyType = with lib.types; attrsOf (oneOf [ (attrsOf base) (listOf base) base ]);
in
{
options.services.pgadmin = {
enable = mkEnableOption "PostgreSQL Admin 4";
enable = lib.mkEnableOption "PostgreSQL Admin 4";
port = mkOption {
port = lib.mkOption {
description = "Port for pgadmin4 to run on";
type = types.port;
type = lib.types.port;
default = 5050;
};
package = mkPackageOption pkgs "pgadmin4" { };
package = lib.mkPackageOption pkgs "pgadmin4" { };
initialEmail = mkOption {
initialEmail = lib.mkOption {
description = "Initial email for the pgAdmin account";
type = types.str;
type = lib.types.str;
};
initialPasswordFile = mkOption {
initialPasswordFile = lib.mkOption {
description = ''
Initial password file for the pgAdmin account. Minimum length by default is 6.
Please see `services.pgadmin.minimumPasswordLength`.
NOTE: Should be string not a store path, to prevent the password from being world readable
'';
type = types.path;
type = lib.types.path;
};
minimumPasswordLength = mkOption {
minimumPasswordLength = lib.mkOption {
description = "Minimum length of the password";
type = types.int;
type = lib.types.int;
default = 6;
};
emailServer = {
enable = mkOption {
enable = lib.mkOption {
description = ''
Enable SMTP email server. This is necessary, if you want to use password recovery or change your own password
'';
type = types.bool;
type = lib.types.bool;
default = false;
};
address = mkOption {
address = lib.mkOption {
description = "SMTP server for email delivery";
type = types.str;
type = lib.types.str;
default = "localhost";
};
port = mkOption {
port = lib.mkOption {
description = "SMTP server port for email delivery";
type = types.port;
type = lib.types.port;
default = 25;
};
useSSL = mkOption {
useSSL = lib.mkOption {
description = "SMTP server should use SSL";
type = types.bool;
type = lib.types.bool;
default = false;
};
useTLS = mkOption {
useTLS = lib.mkOption {
description = "SMTP server should use TLS";
type = types.bool;
type = lib.types.bool;
default = false;
};
username = mkOption {
username = lib.mkOption {
description = "SMTP server username for email delivery";
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
default = null;
};
sender = mkOption {
sender = lib.mkOption {
description = ''
SMTP server sender email for email delivery. Some servers require this to be a valid email address from that server
'';
type = types.str;
type = lib.types.str;
example = "noreply@example.com";
};
passwordFile = mkOption {
passwordFile = lib.mkOption {
description = ''
Password for SMTP email account.
NOTE: Should be string not a store path, to prevent the password from being world readable
'';
type = types.path;
type = lib.types.path;
};
};
openFirewall = mkEnableOption "firewall passthrough for pgadmin4";
openFirewall = lib.mkEnableOption "firewall passthrough for pgadmin4";
settings = mkOption {
settings = lib.mkOption {
description = ''
Settings for pgadmin4.
[Documentation](https://www.pgadmin.org/docs/pgadmin4/development/config_py.html)
@ -118,17 +115,17 @@ in
};
};
config = mkIf (cfg.enable) {
networking.firewall.allowedTCPPorts = mkIf (cfg.openFirewall) [ cfg.port ];
config = lib.mkIf (cfg.enable) {
networking.firewall.allowedTCPPorts = lib.mkIf (cfg.openFirewall) [ cfg.port ];
services.pgadmin.settings = {
DEFAULT_SERVER_PORT = cfg.port;
PASSWORD_LENGTH_MIN = cfg.minimumPasswordLength;
SERVER_MODE = true;
UPGRADE_CHECK_ENABLED = false;
} // (optionalAttrs cfg.openFirewall {
DEFAULT_SERVER = mkDefault "::";
}) // (optionalAttrs cfg.emailServer.enable {
} // (lib.optionalAttrs cfg.openFirewall {
DEFAULT_SERVER = lib.mkDefault "::";
}) // (lib.optionalAttrs cfg.emailServer.enable {
MAIL_SERVER = cfg.emailServer.address;
MAIL_PORT = cfg.emailServer.port;
MAIL_USE_SSL = cfg.emailServer.useSSL;
@ -160,7 +157,7 @@ in
fi
(
# Email address:
echo ${escapeShellArg cfg.initialEmail}
echo ${lib.escapeShellArg cfg.initialEmail}
# file might not contain newline. echo hack fixes that.
PW=$(cat "$PW_FILE")
@ -183,7 +180,7 @@ in
StateDirectory = "pgadmin";
ExecStart = "${cfg.package}/bin/pgadmin4";
LoadCredential = [ "initial_password:${cfg.initialPasswordFile}" ]
++ optional cfg.emailServer.enable "email_password:${cfg.emailServer.passwordFile}";
++ lib.optional cfg.emailServer.enable "email_password:${cfg.emailServer.passwordFile}";
};
};

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (pkgs) mariadb gzip;
@ -12,7 +9,7 @@ let
backupScript = ''
set -o pipefail
failed=""
${concatMapStringsSep "\n" backupDatabaseScript cfg.databases}
${lib.concatMapStringsSep "\n" backupDatabaseScript cfg.databases}
if [ -n "$failed" ]; then
echo "Backup of database(s) failed:$failed"
exit 1
@ -20,7 +17,7 @@ let
'';
backupDatabaseScript = db: ''
dest="${cfg.location}/${db}.gz"
if ${mariadb}/bin/mysqldump ${optionalString cfg.singleTransaction "--single-transaction"} ${db} | ${gzip}/bin/gzip -c ${cfg.gzipOptions} > $dest.tmp; then
if ${mariadb}/bin/mysqldump ${lib.optionalString cfg.singleTransaction "--single-transaction"} ${db} | ${gzip}/bin/gzip -c ${cfg.gzipOptions} > $dest.tmp; then
mv $dest.tmp $dest
echo "Backed up to $dest"
else
@ -37,51 +34,51 @@ in
services.mysqlBackup = {
enable = mkEnableOption "MySQL backups";
enable = lib.mkEnableOption "MySQL backups";
calendar = mkOption {
type = types.str;
calendar = lib.mkOption {
type = lib.types.str;
default = "01:15:00";
description = ''
Configured when to run the backup service systemd unit (DayOfWeek Year-Month-Day Hour:Minute:Second).
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = defaultUser;
description = ''
User to be used to perform backup.
'';
};
databases = mkOption {
databases = lib.mkOption {
default = [];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
List of database names to dump.
'';
};
location = mkOption {
type = types.path;
location = lib.mkOption {
type = lib.types.path;
default = "/var/backup/mysql";
description = ''
Location to put the gzipped MySQL database dumps.
'';
};
singleTransaction = mkOption {
singleTransaction = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Whether to create database dump in a single transaction
'';
};
gzipOptions = mkOption {
gzipOptions = lib.mkOption {
default = "--no-name --rsyncable";
type = types.str;
type = lib.types.str;
description = ''
Command line options to use when invoking `gzip`.
'';
@ -90,8 +87,8 @@ in
};
config = mkIf cfg.enable {
users.users = optionalAttrs (cfg.user == defaultUser) {
config = lib.mkIf cfg.enable {
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
${defaultUser} = {
isSystemUser = true;
createHome = false;
@ -105,9 +102,9 @@ in
ensurePermissions = with lib;
let
privs = "SELECT, SHOW VIEW, TRIGGER, LOCK TABLES";
grant = db: nameValuePair "${db}.*" privs;
grant = db: lib.nameValuePair "${db}.*" privs;
in
listToAttrs (map grant cfg.databases);
lib.listToAttrs (map grant cfg.databases);
}];
systemd = {

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.postgresqlBackup;
@ -13,9 +10,9 @@ let
"gzip" = ".gz";
"zstd" = ".zstd";
};
compressSuffix = getAttr cfg.compression compressSuffixes;
compressSuffix = lib.getAttr cfg.compression compressSuffixes;
compressCmd = getAttr cfg.compression {
compressCmd = lib.getAttr cfg.compression {
"none" = "cat";
"gzip" = "${pkgs.gzip}/bin/gzip -c -${toString cfg.compressionLevel} --rsyncable";
"zstd" = "${pkgs.zstd}/bin/zstd -c -${toString cfg.compressionLevel} --rsyncable";
@ -24,7 +21,7 @@ let
mkSqlPath = prefix: suffix: "${cfg.location}/${db}${prefix}.sql${suffix}";
curFile = mkSqlPath "" compressSuffix;
prevFile = mkSqlPath ".prev" compressSuffix;
prevFiles = map (mkSqlPath ".prev") (attrValues compressSuffixes);
prevFiles = map (mkSqlPath ".prev") (lib.attrValues compressSuffixes);
inProgressFile = mkSqlPath ".in-progress" compressSuffix;
in {
enable = true;
@ -63,7 +60,7 @@ let
in {
imports = [
(mkRemovedOptionModule [ "services" "postgresqlBackup" "period" ] ''
(lib.mkRemovedOptionModule [ "services" "postgresqlBackup" "period" ] ''
A systemd timer is now used instead of cron.
The starting time can be configured via <literal>services.postgresqlBackup.startAt</literal>.
'')
@ -71,11 +68,11 @@ in {
options = {
services.postgresqlBackup = {
enable = mkEnableOption "PostgreSQL dumps";
enable = lib.mkEnableOption "PostgreSQL dumps";
startAt = mkOption {
startAt = lib.mkOption {
default = "*-*-* 01:15:00";
type = with types; either (listOf str) str;
type = with lib.types; either (listOf str) str;
description = ''
This option defines (see `systemd.time` for format) when the
databases should be dumped.
@ -83,9 +80,9 @@ in {
'';
};
backupAll = mkOption {
backupAll = lib.mkOption {
default = cfg.databases == [];
defaultText = literalExpression "services.postgresqlBackup.databases == []";
defaultText = lib.literalExpression "services.postgresqlBackup.databases == []";
type = lib.types.bool;
description = ''
Backup all databases using pg_dumpall.
@ -96,24 +93,24 @@ in {
'';
};
databases = mkOption {
databases = lib.mkOption {
default = [];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
List of database names to dump.
'';
};
location = mkOption {
location = lib.mkOption {
default = "/var/backup/postgresql";
type = types.path;
type = lib.types.path;
description = ''
Path of directory where the PostgreSQL database dumps will be placed.
'';
};
pgdumpOptions = mkOption {
type = types.separatedString " ";
pgdumpOptions = lib.mkOption {
type = lib.types.separatedString " ";
default = "-C";
description = ''
Command line options for pg_dump. This options is not used
@ -123,16 +120,16 @@ in {
'';
};
compression = mkOption {
type = types.enum ["none" "gzip" "zstd"];
compression = lib.mkOption {
type = lib.types.enum ["none" "gzip" "zstd"];
default = "gzip";
description = ''
The type of compression to use on the generated database dump.
'';
};
compressionLevel = mkOption {
type = types.ints.between 1 19;
compressionLevel = lib.mkOption {
type = lib.types.ints.between 1 19;
default = 6;
description = ''
The compression level used when compression is enabled.
@ -143,7 +140,7 @@ in {
};
config = mkMerge [
config = lib.mkMerge [
{
assertions = [
{
@ -158,17 +155,17 @@ in {
}
];
}
(mkIf cfg.enable {
(lib.mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '${cfg.location}' 0700 postgres - - -"
];
})
(mkIf (cfg.enable && cfg.backupAll) {
(lib.mkIf (cfg.enable && cfg.backupAll) {
systemd.services.postgresqlBackup =
postgresqlBackupService "all" "pg_dumpall";
})
(mkIf (cfg.enable && !cfg.backupAll) {
systemd.services = listToAttrs (map (db:
(lib.mkIf (cfg.enable && !cfg.backupAll) {
systemd.services = lib.listToAttrs (map (db:
let
cmd = "pg_dump ${cfg.pgdumpOptions} ${db}";
in {

View File

@ -1,24 +1,21 @@
{ config, lib, pkgs, ... }:
with lib;
let
receiverSubmodule = {
options = {
postgresqlPackage = mkPackageOption pkgs "postgresql" {
postgresqlPackage = lib.mkPackageOption pkgs "postgresql" {
example = "postgresql_15";
};
directory = mkOption {
type = types.path;
example = literalExpression "/mnt/pg_wal/main/";
directory = lib.mkOption {
type = lib.types.path;
example = lib.literalExpression "/mnt/pg_wal/main/";
description = ''
Directory to write the output to.
'';
};
statusInterval = mkOption {
type = types.int;
statusInterval = lib.mkOption {
type = lib.types.int;
default = 10;
description = ''
Specifies the number of seconds between status packets sent back to the server.
@ -28,8 +25,8 @@ let
'';
};
slot = mkOption {
type = types.str;
slot = lib.mkOption {
type = lib.types.str;
default = "";
example = "some_slot_name";
description = ''
@ -45,8 +42,8 @@ let
'';
};
synchronous = mkOption {
type = types.bool;
synchronous = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Flush the WAL data to disk immediately after it has been received.
@ -57,8 +54,8 @@ let
'';
};
compress = mkOption {
type = types.ints.between 0 9;
compress = lib.mkOption {
type = lib.types.ints.between 0 9;
default = 0;
description = ''
Enables gzip compression of write-ahead logs, and specifies the compression level
@ -69,8 +66,8 @@ let
'';
};
connection = mkOption {
type = types.str;
connection = lib.mkOption {
type = lib.types.str;
example = "postgresql://user@somehost";
description = ''
Specifies parameters used to connect to the server, as a connection string.
@ -81,10 +78,10 @@ let
'';
};
extraArgs = mkOption {
type = with types; listOf str;
extraArgs = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
example = literalExpression ''
example = lib.literalExpression ''
[
"--no-sync"
]
@ -94,10 +91,10 @@ let
'';
};
environment = mkOption {
type = with types; attrsOf str;
environment = lib.mkOption {
type = with lib.types; attrsOf str;
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
PGPASSFILE = "/private/passfile";
PGSSLMODE = "require";
@ -114,10 +111,10 @@ let
in {
options = {
services.postgresqlWalReceiver = {
receivers = mkOption {
type = with types; attrsOf (submodule receiverSubmodule);
receivers = lib.mkOption {
type = with lib.types; attrsOf (submodule receiverSubmodule);
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
main = {
postgresqlPackage = pkgs.postgresql_15;
@ -138,7 +135,7 @@ in {
config = let
receivers = config.services.postgresqlWalReceiver.receivers;
in mkIf (receivers != { }) {
in lib.mkIf (receivers != { }) {
users = {
users.postgres = {
uid = config.ids.uids.postgres;
@ -151,18 +148,18 @@ in {
};
};
assertions = concatLists (attrsets.mapAttrsToList (name: config: [
assertions = lib.concatLists (lib.attrsets.mapAttrsToList (name: config: [
{
assertion = config.compress > 0 -> versionAtLeast config.postgresqlPackage.version "10";
assertion = config.compress > 0 -> lib.versionAtLeast config.postgresqlPackage.version "10";
message = "Invalid configuration for WAL receiver \"${name}\": compress requires PostgreSQL version >= 10.";
}
]) receivers);
systemd.tmpfiles.rules = mapAttrsToList (name: config: ''
d ${escapeShellArg config.directory} 0750 postgres postgres - -
systemd.tmpfiles.rules = lib.mapAttrsToList (name: config: ''
d ${lib.escapeShellArg config.directory} 0750 postgres postgres - -
'') receivers;
systemd.services = with attrsets; mapAttrs' (name: config: nameValuePair "postgresql-wal-receiver-${name}" {
systemd.services = lib.mapAttrs' (name: config: lib.nameValuePair "postgresql-wal-receiver-${name}" {
description = "PostgreSQL WAL receiver (${name})";
wantedBy = [ "multi-user.target" ];
startLimitIntervalSec = 0; # retry forever, useful in case of network disruption
@ -179,22 +176,22 @@ in {
script = let
receiverCommand = postgresqlPackage:
if (versionAtLeast postgresqlPackage.version "10")
if (lib.versionAtLeast postgresqlPackage.version "10")
then "${postgresqlPackage}/bin/pg_receivewal"
else "${postgresqlPackage}/bin/pg_receivexlog";
in ''
${receiverCommand config.postgresqlPackage} \
--no-password \
--directory=${escapeShellArg config.directory} \
--directory=${lib.escapeShellArg config.directory} \
--status-interval=${toString config.statusInterval} \
--dbname=${escapeShellArg config.connection} \
${optionalString (config.compress > 0) "--compress=${toString config.compress}"} \
${optionalString (config.slot != "") "--slot=${escapeShellArg config.slot}"} \
${optionalString config.synchronous "--synchronous"} \
${concatStringsSep " " config.extraArgs}
--dbname=${lib.escapeShellArg config.connection} \
${lib.optionalString (config.compress > 0) "--compress=${toString config.compress}"} \
${lib.optionalString (config.slot != "") "--slot=${lib.escapeShellArg config.slot}"} \
${lib.optionalString config.synchronous "--synchronous"} \
${lib.concatStringsSep " " config.extraArgs}
'';
}) receivers;
};
meta.maintainers = with maintainers; [ pacien ];
meta.maintainers = with lib.maintainers; [ pacien ];
}

View File

@ -1,32 +1,29 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.restic.server;
in
{
meta.maintainers = [ maintainers.bachp ];
meta.maintainers = [ lib.maintainers.bachp ];
options.services.restic.server = {
enable = mkEnableOption "Restic REST Server";
enable = lib.mkEnableOption "Restic REST Server";
listenAddress = mkOption {
listenAddress = lib.mkOption {
default = "8000";
example = "127.0.0.1:8080";
type = types.str;
type = lib.types.str;
description = "Listen on a specific IP address and port or unix socket.";
};
dataDir = mkOption {
dataDir = lib.mkOption {
default = "/var/lib/restic";
type = types.path;
type = lib.types.path;
description = "The directory for storing the restic repository.";
};
appendOnly = mkOption {
appendOnly = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Enable append only mode.
This mode allows creation of new backups but prevents deletion and modification of existing backups.
@ -34,33 +31,33 @@ in
'';
};
privateRepos = mkOption {
privateRepos = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Enable private repos.
Grants access only when a subdirectory with the same name as the user is specified in the repository URL.
'';
};
prometheus = mkOption {
prometheus = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = "Enable Prometheus metrics at /metrics.";
};
extraFlags = mkOption {
type = types.listOf types.str;
extraFlags = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
Extra commandline options to pass to Restic REST server.
'';
};
package = mkPackageOption pkgs "restic-rest-server" { };
package = lib.mkPackageOption pkgs "restic-rest-server" { };
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [{
assertion = lib.substring 0 1 cfg.listenAddress != ":";
message = "The restic-rest-server now uses systemd socket activation, which expects only the Port number: services.restic.server.listenAddress = \"${lib.substring 1 6 cfg.listenAddress}\";";
@ -75,10 +72,10 @@ in
ExecStart = ''
${cfg.package}/bin/rest-server \
--path ${cfg.dataDir} \
${optionalString cfg.appendOnly "--append-only"} \
${optionalString cfg.privateRepos "--private-repos"} \
${optionalString cfg.prometheus "--prometheus"} \
${escapeShellArgs cfg.extraFlags} \
${lib.optionalString cfg.appendOnly "--append-only"} \
${lib.optionalString cfg.privateRepos "--private-repos"} \
${lib.optionalString cfg.prometheus "--prometheus"} \
${lib.escapeShellArgs cfg.extraFlags} \
'';
Type = "simple";
User = "restic";
@ -119,7 +116,7 @@ in
wantedBy = [ "sockets.target" ];
};
systemd.tmpfiles.rules = mkIf cfg.privateRepos [
systemd.tmpfiles.rules = lib.mkIf cfg.privateRepos [
"f ${cfg.dataDir}/.htpasswd 0700 restic restic -"
];

View File

@ -1,28 +1,25 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
inherit (utils.systemdUtils.unitOptions) unitOption;
in
{
options.services.restic.backups = mkOption {
options.services.restic.backups = lib.mkOption {
description = ''
Periodic backups to create with Restic.
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
passwordFile = mkOption {
type = types.str;
passwordFile = lib.mkOption {
type = lib.types.str;
description = ''
Read the repository password from a file.
'';
example = "/etc/nixos/restic-password";
};
environmentFile = mkOption {
type = with types; nullOr str;
environmentFile = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
file containing the credentials to access the repository, in the
@ -30,8 +27,8 @@ in
'';
};
rcloneOptions = mkOption {
type = with types; nullOr (attrsOf (oneOf [ str bool ]));
rcloneOptions = lib.mkOption {
type = with lib.types; nullOr (attrsOf (oneOf [ str bool ]));
default = null;
description = ''
Options to pass to rclone to control its behavior.
@ -47,8 +44,8 @@ in
};
};
rcloneConfig = mkOption {
type = with types; nullOr (attrsOf (oneOf [ str bool ]));
rcloneConfig = lib.mkOption {
type = with lib.types; nullOr (attrsOf (oneOf [ str bool ]));
default = null;
description = ''
Configuration for the rclone remote being used for backup.
@ -71,8 +68,8 @@ in
};
};
rcloneConfigFile = mkOption {
type = with types; nullOr path;
rcloneConfigFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
Path to the file containing rclone configuration. This file
@ -83,17 +80,17 @@ in
'';
};
inhibitsSleep = mkOption {
inhibitsSleep = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
example = true;
description = ''
Prevents the system from sleeping while backing up.
'';
};
repository = mkOption {
type = with types; nullOr str;
repository = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
repository to backup to.
@ -101,18 +98,18 @@ in
example = "sftp:backup@192.168.1.100:/backups/${name}";
};
repositoryFile = mkOption {
type = with types; nullOr path;
repositoryFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
Path to the file containing the repository location to backup to.
'';
};
paths = mkOption {
paths = lib.mkOption {
# This is nullable for legacy reasons only. We should consider making it a pure listOf
# after some time has passed since this comment was added.
type = types.nullOr (types.listOf types.str);
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = [ ];
description = ''
Which paths to backup, in addition to ones specified via
@ -126,8 +123,8 @@ in
];
};
exclude = mkOption {
type = types.listOf types.str;
exclude = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Patterns to exclude when backing up. See
@ -141,8 +138,8 @@ in
];
};
timerConfig = mkOption {
type = types.nullOr (types.attrsOf unitOption);
timerConfig = lib.mkOption {
type = lib.types.nullOr (lib.types.attrsOf unitOption);
default = {
OnCalendar = "daily";
Persistent = true;
@ -159,8 +156,8 @@ in
};
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "root";
description = ''
As which user the backup should run.
@ -168,8 +165,8 @@ in
example = "postgresql";
};
extraBackupArgs = mkOption {
type = types.listOf types.str;
extraBackupArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Extra arguments passed to restic backup.
@ -179,8 +176,8 @@ in
];
};
extraOptions = mkOption {
type = types.listOf types.str;
extraOptions = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Extra extended options to be passed to the restic --option flag.
@ -190,16 +187,16 @@ in
];
};
initialize = mkOption {
type = types.bool;
initialize = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Create the repository if it doesn't exist.
'';
};
pruneOpts = mkOption {
type = types.listOf types.str;
pruneOpts = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
A list of options (--keep-\* et al.) for 'restic forget
@ -215,16 +212,16 @@ in
];
};
runCheck = mkOption {
type = types.bool;
runCheck = lib.mkOption {
type = lib.types.bool;
default = (builtins.length config.services.restic.backups.${name}.checkOpts > 0);
defaultText = literalExpression ''builtins.length config.services.backups.${name}.checkOpts > 0'';
defaultText = lib.literalExpression ''builtins.length config.services.backups.${name}.checkOpts > 0'';
description = "Whether to run the `check` command with the provided `checkOpts` options.";
example = true;
};
checkOpts = mkOption {
type = types.listOf types.str;
checkOpts = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
A list of options for 'restic check'.
@ -234,8 +231,8 @@ in
];
};
dynamicFilesFrom = mkOption {
type = with types; nullOr str;
dynamicFilesFrom = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
A script that produces a list of files to back up. The
@ -245,23 +242,23 @@ in
example = "find /home/matt/git -type d -name .git";
};
backupPrepareCommand = mkOption {
type = with types; nullOr str;
backupPrepareCommand = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
A script that must run before starting the backup process.
'';
};
backupCleanupCommand = mkOption {
type = with types; nullOr str;
backupCleanupCommand = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
A script that must run after finishing the backup process.
'';
};
package = mkPackageOption pkgs "restic" { };
package = lib.mkPackageOption pkgs "restic" { };
createWrapper = lib.mkOption {
type = lib.types.bool;
@ -299,54 +296,54 @@ in
};
config = {
assertions = mapAttrsToList (n: v: {
assertions = lib.mapAttrsToList (n: v: {
assertion = (v.repository == null) != (v.repositoryFile == null);
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
}) config.services.restic.backups;
systemd.services =
mapAttrs'
lib.mapAttrs'
(name: backup:
let
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
inhibitCmd = concatStringsSep " " [
extraOptions = lib.concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
inhibitCmd = lib.concatStringsSep " " [
"${pkgs.systemd}/bin/systemd-inhibit"
"--mode='block'"
"--who='restic'"
"--what='sleep'"
"--why=${escapeShellArg "Scheduled backup ${name}"} "
"--why=${lib.escapeShellArg "Scheduled backup ${name}"} "
];
resticCmd = "${optionalString backup.inhibitsSleep inhibitCmd}${backup.package}/bin/restic${extraOptions}";
excludeFlags = optional (backup.exclude != []) "--exclude-file=${pkgs.writeText "exclude-patterns" (concatStringsSep "\n" backup.exclude)}";
resticCmd = "${lib.optionalString backup.inhibitsSleep inhibitCmd}${backup.package}/bin/restic${extraOptions}";
excludeFlags = lib.optional (backup.exclude != []) "--exclude-file=${pkgs.writeText "exclude-patterns" (lib.concatStringsSep "\n" backup.exclude)}";
filesFromTmpFile = "/run/restic-backups-${name}/includes";
doBackup = (backup.dynamicFilesFrom != null) || (backup.paths != null && backup.paths != []);
pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [
(resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts))
pruneCmd = lib.optionals (builtins.length backup.pruneOpts > 0) [
(resticCmd + " forget --prune " + (lib.concatStringsSep " " backup.pruneOpts))
];
checkCmd = optionals backup.runCheck [
(resticCmd + " check " + (concatStringsSep " " backup.checkOpts))
checkCmd = lib.optionals backup.runCheck [
(resticCmd + " check " + (lib.concatStringsSep " " backup.checkOpts))
];
# Helper functions for rclone remotes
rcloneRemoteName = builtins.elemAt (splitString ":" backup.repository) 1;
rcloneAttrToOpt = v: "RCLONE_" + toUpper (builtins.replaceStrings [ "-" ] [ "_" ] v);
rcloneAttrToConf = v: "RCLONE_CONFIG_" + toUpper (rcloneRemoteName + "_" + v);
rcloneRemoteName = builtins.elemAt (lib.splitString ":" backup.repository) 1;
rcloneAttrToOpt = v: "RCLONE_" + lib.toUpper (builtins.replaceStrings [ "-" ] [ "_" ] v);
rcloneAttrToConf = v: "RCLONE_CONFIG_" + lib.toUpper (rcloneRemoteName + "_" + v);
toRcloneVal = v: if lib.isBool v then lib.boolToString v else v;
in
nameValuePair "restic-backups-${name}" ({
lib.nameValuePair "restic-backups-${name}" ({
environment = {
# not %C, because that wouldn't work in the wrapper script
RESTIC_CACHE_DIR = "/var/cache/restic-backups-${name}";
RESTIC_PASSWORD_FILE = backup.passwordFile;
RESTIC_REPOSITORY = backup.repository;
RESTIC_REPOSITORY_FILE = backup.repositoryFile;
} // optionalAttrs (backup.rcloneOptions != null) (mapAttrs'
} // lib.optionalAttrs (backup.rcloneOptions != null) (lib.mapAttrs'
(name: value:
nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
lib.nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
)
backup.rcloneOptions) // optionalAttrs (backup.rcloneConfigFile != null) {
backup.rcloneOptions) // lib.optionalAttrs (backup.rcloneConfigFile != null) {
RCLONE_CONFIG = backup.rcloneConfigFile;
} // optionalAttrs (backup.rcloneConfig != null) (mapAttrs'
} // lib.optionalAttrs (backup.rcloneConfig != null) (lib.mapAttrs'
(name: value:
nameValuePair (rcloneAttrToConf name) (toRcloneVal value)
lib.nameValuePair (rcloneAttrToConf name) (toRcloneVal value)
)
backup.rcloneConfig);
path = [ config.programs.ssh.package ];
@ -355,37 +352,37 @@ in
after = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = (optionals doBackup [ "${resticCmd} backup ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} --files-from=${filesFromTmpFile}" ])
ExecStart = (lib.optionals doBackup [ "${resticCmd} backup ${lib.concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} --files-from=${filesFromTmpFile}" ])
++ pruneCmd ++ checkCmd;
User = backup.user;
RuntimeDirectory = "restic-backups-${name}";
CacheDirectory = "restic-backups-${name}";
CacheDirectoryMode = "0700";
PrivateTmp = true;
} // optionalAttrs (backup.environmentFile != null) {
} // lib.optionalAttrs (backup.environmentFile != null) {
EnvironmentFile = backup.environmentFile;
};
} // optionalAttrs (backup.initialize || doBackup || backup.backupPrepareCommand != null) {
} // lib.optionalAttrs (backup.initialize || doBackup || backup.backupPrepareCommand != null) {
preStart = ''
${optionalString (backup.backupPrepareCommand != null) ''
${lib.optionalString (backup.backupPrepareCommand != null) ''
${pkgs.writeScript "backupPrepareCommand" backup.backupPrepareCommand}
''}
${optionalString (backup.initialize) ''
${lib.optionalString (backup.initialize) ''
${resticCmd} cat config > /dev/null || ${resticCmd} init
''}
${optionalString (backup.paths != null && backup.paths != []) ''
cat ${pkgs.writeText "staticPaths" (concatLines backup.paths)} >> ${filesFromTmpFile}
${lib.optionalString (backup.paths != null && backup.paths != []) ''
cat ${pkgs.writeText "staticPaths" (lib.concatLines backup.paths)} >> ${filesFromTmpFile}
''}
${optionalString (backup.dynamicFilesFrom != null) ''
${lib.optionalString (backup.dynamicFilesFrom != null) ''
${pkgs.writeScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile}
''}
'';
} // optionalAttrs (doBackup || backup.backupCleanupCommand != null) {
} // lib.optionalAttrs (doBackup || backup.backupCleanupCommand != null) {
postStop = ''
${optionalString (backup.backupCleanupCommand != null) ''
${lib.optionalString (backup.backupCleanupCommand != null) ''
${pkgs.writeScript "backupCleanupCommand" backup.backupCleanupCommand}
''}
${optionalString doBackup ''
${lib.optionalString doBackup ''
rm ${filesFromTmpFile}
''}
'';
@ -393,12 +390,12 @@ in
)
config.services.restic.backups;
systemd.timers =
mapAttrs'
(name: backup: nameValuePair "restic-backups-${name}" {
lib.mapAttrs'
(name: backup: lib.nameValuePair "restic-backups-${name}" {
wantedBy = [ "timers.target" ];
timerConfig = backup.timerConfig;
})
(filterAttrs (_: backup: backup.timerConfig != null) config.services.restic.backups);
(lib.filterAttrs (_: backup: backup.timerConfig != null) config.services.restic.backups);
# generate wrapper scripts, as described in the createWrapper option
environment.systemPackages = lib.mapAttrsToList (name: backup: let

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rsnapshot;
cfgfile = pkgs.writeText "rsnapshot.conf" ''
@ -22,21 +19,21 @@ in
{
options = {
services.rsnapshot = {
enable = mkEnableOption "rsnapshot backups";
enableManualRsnapshot = mkOption {
enable = lib.mkEnableOption "rsnapshot backups";
enableManualRsnapshot = lib.mkOption {
description = "Whether to enable manual usage of the rsnapshot command with this module.";
default = true;
type = types.bool;
type = lib.types.bool;
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
example = ''
retains hourly 24
retain daily 365
backup /home/ localhost/
'';
type = types.lines;
type = lib.types.lines;
description = ''
rsnapshot configuration option in addition to the defaults from
rsnapshot and this module.
@ -49,10 +46,10 @@ in
'';
};
cronIntervals = mkOption {
cronIntervals = lib.mkOption {
default = {};
example = { hourly = "0 * * * *"; daily = "50 21 * * *"; };
type = types.attrsOf types.str;
type = lib.types.attrsOf lib.types.str;
description = ''
Periodicity at which intervals should be run by cron.
Note that the intervals also have to exist in configuration
@ -62,12 +59,12 @@ in
};
};
config = mkIf cfg.enable (mkMerge [
config = lib.mkIf cfg.enable (lib.mkMerge [
{
services.cron.systemCronJobs =
mapAttrsToList (interval: time: "${time} root ${pkgs.rsnapshot}/bin/rsnapshot -c ${cfgfile} ${interval}") cfg.cronIntervals;
lib.mapAttrsToList (interval: time: "${time} root ${pkgs.rsnapshot}/bin/rsnapshot -c ${cfgfile} ${interval}") cfg.cronIntervals;
}
(mkIf cfg.enableManualRsnapshot {
(lib.mkIf cfg.enableManualRsnapshot {
environment.systemPackages = [ pkgs.rsnapshot ];
environment.etc."rsnapshot.conf".source = cfgfile;
})

View File

@ -1,85 +1,82 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.sanoid;
datasetSettingsType = with types;
datasetSettingsType = with lib.types;
(attrsOf (nullOr (oneOf [ str int bool (listOf str) ]))) // {
description = "dataset/template options";
};
commonOptions = {
hourly = mkOption {
hourly = lib.mkOption {
description = "Number of hourly snapshots.";
type = with types; nullOr ints.unsigned;
type = with lib.types; nullOr ints.unsigned;
default = null;
};
daily = mkOption {
daily = lib.mkOption {
description = "Number of daily snapshots.";
type = with types; nullOr ints.unsigned;
type = with lib.types; nullOr ints.unsigned;
default = null;
};
monthly = mkOption {
monthly = lib.mkOption {
description = "Number of monthly snapshots.";
type = with types; nullOr ints.unsigned;
type = with lib.types; nullOr ints.unsigned;
default = null;
};
yearly = mkOption {
yearly = lib.mkOption {
description = "Number of yearly snapshots.";
type = with types; nullOr ints.unsigned;
type = with lib.types; nullOr ints.unsigned;
default = null;
};
autoprune = mkOption {
autoprune = lib.mkOption {
description = "Whether to automatically prune old snapshots.";
type = with types; nullOr bool;
type = with lib.types; nullOr bool;
default = null;
};
autosnap = mkOption {
autosnap = lib.mkOption {
description = "Whether to automatically take snapshots.";
type = with types; nullOr bool;
type = with lib.types; nullOr bool;
default = null;
};
};
datasetOptions = rec {
use_template = mkOption {
use_template = lib.mkOption {
description = "Names of the templates to use for this dataset.";
type = types.listOf (types.str // {
check = (types.enum (attrNames cfg.templates)).check;
type = lib.types.listOf (lib.types.str // {
check = (lib.types.enum (lib.attrNames cfg.templates)).check;
description = "configured template name";
});
default = [ ];
};
useTemplate = use_template;
recursive = mkOption {
recursive = lib.mkOption {
description = ''
Whether to recursively snapshot dataset children.
You can also set this to `"zfs"` to handle datasets
recursively in an atomic way without the possibility to
override settings for child datasets.
'';
type = with types; oneOf [ bool (enum [ "zfs" ]) ];
type = with lib.types; oneOf [ bool (enum [ "zfs" ]) ];
default = false;
};
process_children_only = mkOption {
process_children_only = lib.mkOption {
description = "Whether to only snapshot child datasets if recursing.";
type = types.bool;
type = lib.types.bool;
default = false;
};
processChildrenOnly = process_children_only;
};
# Extract unique dataset names
datasets = unique (attrNames cfg.datasets);
datasets = lib.unique (lib.attrNames cfg.datasets);
# Function to build "zfs allow" and "zfs unallow" commands for the
# filesystems we've delegated permissions to.
@ -88,23 +85,23 @@ let
"-+/run/booted-system/sw/bin/zfs"
zfsAction
"sanoid"
(concatStringsSep "," permissions)
(lib.concatStringsSep "," permissions)
dataset
];
configFile =
let
mkValueString = v:
if builtins.isList v then concatStringsSep "," v
else generators.mkValueStringDefault { } v;
if lib.isList v then lib.concatStringsSep "," v
else lib.generators.mkValueStringDefault { } v;
mkKeyValue = k: v:
if v == null then ""
else if k == "processChildrenOnly" then ""
else if k == "useTemplate" then ""
else generators.mkKeyValueDefault { inherit mkValueString; } "=" k v;
else lib.generators.mkKeyValueDefault { inherit mkValueString; } "=" k v;
in
generators.toINI { inherit mkKeyValue; } cfg.settings;
lib.generators.toINI { inherit mkKeyValue; } cfg.settings;
in
{
@ -112,12 +109,12 @@ in
# Interface
options.services.sanoid = {
enable = mkEnableOption "Sanoid ZFS snapshotting service";
enable = lib.mkEnableOption "Sanoid ZFS snapshotting service";
package = lib.mkPackageOption pkgs "sanoid" {};
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "hourly";
example = "daily";
description = ''
@ -128,19 +125,19 @@ in
'';
};
datasets = mkOption {
type = types.attrsOf (types.submodule ({ config, options, ... }: {
datasets = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ config, options, ... }: {
freeformType = datasetSettingsType;
options = commonOptions // datasetOptions;
config.use_template = modules.mkAliasAndWrapDefsWithPriority id (options.useTemplate or { });
config.process_children_only = modules.mkAliasAndWrapDefsWithPriority id (options.processChildrenOnly or { });
config.use_template = lib.modules.mkAliasAndWrapDefsWithPriority lib.id (options.useTemplate or { });
config.process_children_only = lib.modules.mkAliasAndWrapDefsWithPriority lib.id (options.processChildrenOnly or { });
}));
default = { };
description = "Datasets to snapshot.";
};
templates = mkOption {
type = types.attrsOf (types.submodule {
templates = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule {
freeformType = datasetSettingsType;
options = commonOptions;
});
@ -148,8 +145,8 @@ in
description = "Templates for datasets.";
};
settings = mkOption {
type = types.attrsOf datasetSettingsType;
settings = lib.mkOption {
type = lib.types.attrsOf datasetSettingsType;
description = ''
Free-form settings written directly to the config file. See
<https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.defaults.conf>
@ -157,8 +154,8 @@ in
'';
};
extraArgs = mkOption {
type = types.listOf types.str;
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "--verbose" "--readonly" "--debug" ];
description = ''
@ -171,10 +168,10 @@ in
# Implementation
config = mkIf cfg.enable {
services.sanoid.settings = mkMerge [
(mapAttrs' (d: v: nameValuePair ("template_" + d) v) cfg.templates)
(mapAttrs (d: v: v) cfg.datasets)
config = lib.mkIf cfg.enable {
services.sanoid.settings = lib.mkMerge [
(lib.mapAttrs' (d: v: lib.nameValuePair ("template_" + d) v) cfg.templates)
(lib.mapAttrs (d: v: v) cfg.datasets)
];
systemd.services.sanoid = {
@ -201,5 +198,5 @@ in
};
};
meta.maintainers = with maintainers; [ lopsided98 ];
meta.maintainers = with lib.maintainers; [ lopsided98 ];
}

View File

@ -1,18 +1,15 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.services.snapraid;
in
{
imports = [
# Should have never been on the top-level.
(mkRenamedOptionModule [ "snapraid" ] [ "services" "snapraid" ])
(lib.mkRenamedOptionModule [ "snapraid" ] [ "services" "snapraid" ])
];
options.services.snapraid = with types; {
enable = mkEnableOption "SnapRAID";
dataDisks = mkOption {
options.services.snapraid = with lib.types; {
enable = lib.mkEnableOption "SnapRAID";
dataDisks = lib.mkOption {
default = { };
example = {
d1 = "/mnt/disk1/";
@ -22,7 +19,7 @@ in
description = "SnapRAID data disks.";
type = attrsOf str;
};
parityFiles = mkOption {
parityFiles = lib.mkOption {
default = [ ];
example = [
"/mnt/diskp/snapraid.parity"
@ -35,7 +32,7 @@ in
description = "SnapRAID parity files.";
type = listOf str;
};
contentFiles = mkOption {
contentFiles = lib.mkOption {
default = [ ];
example = [
"/var/snapraid.content"
@ -45,40 +42,40 @@ in
description = "SnapRAID content list files.";
type = listOf str;
};
exclude = mkOption {
exclude = lib.mkOption {
default = [ ];
example = [ "*.unrecoverable" "/tmp/" "/lost+found/" ];
description = "SnapRAID exclude directives.";
type = listOf str;
};
touchBeforeSync = mkOption {
touchBeforeSync = lib.mkOption {
default = true;
example = false;
description =
"Whether {command}`snapraid touch` should be run before {command}`snapraid sync`.";
type = bool;
};
sync.interval = mkOption {
sync.interval = lib.mkOption {
default = "01:00";
example = "daily";
description = "How often to run {command}`snapraid sync`.";
type = str;
};
scrub = {
interval = mkOption {
interval = lib.mkOption {
default = "Mon *-*-* 02:00:00";
example = "weekly";
description = "How often to run {command}`snapraid scrub`.";
type = str;
};
plan = mkOption {
plan = lib.mkOption {
default = 8;
example = 5;
description =
"Percent of the array that should be checked by {command}`snapraid scrub`.";
type = int;
};
olderThan = mkOption {
olderThan = lib.mkOption {
default = 10;
example = 20;
description =
@ -86,7 +83,7 @@ in
type = int;
};
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
example = ''
nohidden
@ -105,7 +102,7 @@ in
nParity = builtins.length cfg.parityFiles;
mkPrepend = pre: s: pre + s;
in
mkIf cfg.enable {
lib.mkIf cfg.enable {
assertions = [
{
assertion = nParity <= 6;
@ -128,9 +125,9 @@ in
prependContent = mkPrepend "content ";
prependExclude = mkPrepend "exclude ";
in
concatStringsSep "\n"
lib.concatStringsSep "\n"
(map prependData
((mapAttrsToList (name: value: name + " " + value)) dataDisks)
((lib.mapAttrsToList (name: value: name + " " + value)) dataDisks)
++ zipListsWith (a: b: a + b)
([ "parity " ] ++ map (i: toString i + "-parity ") (range 2 6))
parityFiles ++ map prependContent contentFiles
@ -179,8 +176,8 @@ in
let
contentDirs = map dirOf contentFiles;
in
unique (
attrValues dataDisks ++ contentDirs
lib.unique (
lib.attrValues dataDisks ++ contentDirs
);
};
unitConfig.After = "snapraid-sync.service";
@ -227,10 +224,10 @@ in
# https://www.snapraid.it/manual#7.1
splitParityFiles = map (s: splitString "," s) parityFiles;
in
unique (
attrValues dataDisks ++ splitParityFiles ++ contentDirs
lib.unique (
lib.attrValues dataDisks ++ splitParityFiles ++ contentDirs
);
} // optionalAttrs touchBeforeSync {
} // lib.optionalAttrs touchBeforeSync {
ExecStartPre = "${pkgs.snapraid}/bin/snapraid touch";
};
};

View File

@ -1,14 +1,11 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.syncoid;
# Extract local dasaset names (so no datasets containing "@")
localDatasetName = d: optionals (d != null) (
localDatasetName = d: lib.optionals (d != null) (
let m = builtins.match "([^/@]+[^@]*)" d; in
optionals (m != null) m
lib.optionals (m != null) m
);
# Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
@ -35,7 +32,7 @@ let
"/run/booted-system/sw/bin/zfs"
"allow"
cfg.user
(concatStringsSep "," permissions)
(lib.concatStringsSep "," permissions)
dataset
]}
${lib.optionalString ((builtins.dirOf dataset) != ".") ''
@ -44,7 +41,7 @@ let
"/run/booted-system/sw/bin/zfs"
"allow"
cfg.user
(concatStringsSep "," permissions)
(lib.concatStringsSep "," permissions)
# Remove the last part of the path
(builtins.dirOf dataset)
]}
@ -66,14 +63,14 @@ let
"/run/booted-system/sw/bin/zfs"
"unallow"
cfg.user
(concatStringsSep "," permissions)
(lib.concatStringsSep "," permissions)
dataset
]}
${lib.optionalString ((builtins.dirOf dataset) != ".") (lib.escapeShellArgs [
"/run/booted-system/sw/bin/zfs"
"unallow"
cfg.user
(concatStringsSep "," permissions)
(lib.concatStringsSep "," permissions)
# Remove the last part of the path
(builtins.dirOf dataset)
])}
@ -85,12 +82,12 @@ in
# Interface
options.services.syncoid = {
enable = mkEnableOption "Syncoid ZFS synchronization service";
enable = lib.mkEnableOption "Syncoid ZFS synchronization service";
package = lib.mkPackageOption pkgs "sanoid" {};
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "hourly";
example = "*-*-* *:15:00";
description = ''
@ -101,8 +98,8 @@ in
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "syncoid";
example = "backup";
description = ''
@ -115,15 +112,15 @@ in
'';
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "syncoid";
example = "backup";
description = "The group for the service.";
};
sshKey = mkOption {
type = with types; nullOr (coercedTo path toString str);
sshKey = lib.mkOption {
type = with lib.types; nullOr (coercedTo path toString str);
default = null;
description = ''
SSH private key file to use to login to the remote system. Can be
@ -131,8 +128,8 @@ in
'';
};
localSourceAllow = mkOption {
type = types.listOf types.str;
localSourceAllow = lib.mkOption {
type = lib.types.listOf lib.types.str;
# Permissions snapshot and destroy are in case --no-sync-snap is not used
default = [ "bookmark" "hold" "send" "snapshot" "destroy" "mount" ];
description = ''
@ -143,8 +140,8 @@ in
'';
};
localTargetAllow = mkOption {
type = types.listOf types.str;
localTargetAllow = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "change-key" "compression" "create" "mount" "mountpoint" "receive" "rollback" ];
example = [ "create" "mount" "receive" "rollback" ];
description = ''
@ -158,8 +155,8 @@ in
'';
};
commonArgs = mkOption {
type = types.listOf types.str;
commonArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "--no-sync-snap" ];
description = ''
@ -170,19 +167,19 @@ in
'';
};
service = mkOption {
type = types.attrs;
service = lib.mkOption {
type = lib.types.attrs;
default = { };
description = ''
Systemd configuration common to all syncoid services.
'';
};
commands = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
commands = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
source = mkOption {
type = types.str;
source = lib.mkOption {
type = lib.types.str;
example = "pool/dataset";
description = ''
Source ZFS dataset. Can be either local or remote. Defaults to
@ -190,8 +187,8 @@ in
'';
};
target = mkOption {
type = types.str;
target = lib.mkOption {
type = lib.types.str;
example = "user@server:pool/dataset";
description = ''
Target ZFS dataset. Can be either local
@ -200,18 +197,18 @@ in
'';
};
recursive = mkEnableOption ''the transfer of child datasets'';
recursive = lib.mkEnableOption ''the transfer of child datasets'';
sshKey = mkOption {
type = with types; nullOr (coercedTo path toString str);
sshKey = lib.mkOption {
type = with lib.types; nullOr (coercedTo path toString str);
description = ''
SSH private key file to use to login to the remote system.
Defaults to {option}`services.syncoid.sshKey` option.
'';
};
localSourceAllow = mkOption {
type = types.listOf types.str;
localSourceAllow = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Permissions granted for the {option}`services.syncoid.user` user
for local source datasets. See
@ -221,8 +218,8 @@ in
'';
};
localTargetAllow = mkOption {
type = types.listOf types.str;
localTargetAllow = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Permissions granted for the {option}`services.syncoid.user` user
for local target datasets. See
@ -234,8 +231,8 @@ in
'';
};
sendOptions = mkOption {
type = types.separatedString " ";
sendOptions = lib.mkOption {
type = lib.types.separatedString " ";
default = "";
example = "Lc e";
description = ''
@ -244,8 +241,8 @@ in
'';
};
recvOptions = mkOption {
type = types.separatedString " ";
recvOptions = lib.mkOption {
type = lib.types.separatedString " ";
default = "";
example = "ux recordsize o compression=lz4";
description = ''
@ -254,38 +251,38 @@ in
'';
};
useCommonArgs = mkOption {
type = types.bool;
useCommonArgs = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to add the configured common arguments to this command.
'';
};
service = mkOption {
type = types.attrs;
service = lib.mkOption {
type = lib.types.attrs;
default = { };
description = ''
Systemd configuration specific to this syncoid service.
'';
};
extraArgs = mkOption {
type = types.listOf types.str;
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "--sshport 2222" ];
description = "Extra syncoid arguments for this command.";
};
};
config = {
source = mkDefault name;
sshKey = mkDefault cfg.sshKey;
localSourceAllow = mkDefault cfg.localSourceAllow;
localTargetAllow = mkDefault cfg.localTargetAllow;
source = lib.mkDefault name;
sshKey = lib.mkDefault cfg.sshKey;
localSourceAllow = lib.mkDefault cfg.localSourceAllow;
localTargetAllow = lib.mkDefault cfg.localTargetAllow;
};
}));
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
"pool/test".target = "root@target:pool/test";
}
@ -296,9 +293,9 @@ in
# Implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users = {
users = mkIf (cfg.user == "syncoid") {
users = lib.mkIf (cfg.user == "syncoid") {
syncoid = {
group = cfg.group;
isSystemUser = true;
@ -308,14 +305,14 @@ in
createHome = false;
};
};
groups = mkIf (cfg.group == "syncoid") {
groups = lib.mkIf (cfg.group == "syncoid") {
syncoid = { };
};
};
systemd.services = mapAttrs'
systemd.services = lib.mapAttrs'
(name: c:
nameValuePair "syncoid-${escapeUnitName name}" (mkMerge [
lib.nameValuePair "syncoid-${lib.escapeUnitName name}" (lib.mkMerge [
{
description = "Syncoid ZFS synchronization from ${c.source} to ${c.target}";
after = [ "zfs.target" ];
@ -330,9 +327,9 @@ in
(map (buildUnallowCommand c.localSourceAllow) (localDatasetName c.source)) ++
(map (buildUnallowCommand c.localTargetAllow) (localDatasetName c.target));
ExecStart = lib.escapeShellArgs ([ "${cfg.package}/bin/syncoid" ]
++ optionals c.useCommonArgs cfg.commonArgs
++ optional c.recursive "-r"
++ optionals (c.sshKey != null) [ "--sshkey" c.sshKey ]
++ lib.optionals c.useCommonArgs cfg.commonArgs
++ lib.optional c.recursive "-r"
++ lib.optionals (c.sshKey != null) [ "--sshkey" c.sshKey ]
++ c.extraArgs
++ [
"--sendoptions"
@ -364,7 +361,7 @@ in
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateNetwork = mkDefault false;
PrivateNetwork = lib.mkDefault false;
PrivateUsers = false; # Enabling this breaks on zfs-2.2.0
ProtectClock = true;
ProtectControlGroups = true;
@ -379,15 +376,15 @@ in
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RootDirectory = "/run/syncoid/${escapeUnitName name}";
RootDirectory = "/run/syncoid/${lib.escapeUnitName name}";
RootDirectoryStartOnly = true;
BindPaths = [ "/dev/zfs" ];
BindReadOnlyPaths = [ builtins.storeDir "/etc" "/run" "/bin/sh" ];
# Avoid useless mounting of RootDirectory= in the own RootDirectory= of ExecStart='s mount namespace.
InaccessiblePaths = [ "-+/run/syncoid/${escapeUnitName name}" ];
InaccessiblePaths = [ "-+/run/syncoid/${lib.escapeUnitName name}" ];
MountAPIVFS = true;
# Create RootDirectory= in the host's mount namespace.
RuntimeDirectory = [ "syncoid/${escapeUnitName name}" ];
RuntimeDirectory = [ "syncoid/${lib.escapeUnitName name}" ];
RuntimeDirectoryMode = "700";
SystemCallFilter = [
"@system-service"
@ -416,5 +413,5 @@ in
cfg.commands;
};
meta.maintainers = with maintainers; [ julm lopsided98 ];
meta.maintainers = with lib.maintainers; [ julm lopsided98 ];
}

View File

@ -1,41 +1,38 @@
{ config, lib, options, pkgs, utils, ... }:
with lib;
let
gcfg = config.services.tarsnap;
opt = options.services.tarsnap;
configFile = name: cfg: ''
keyfile ${cfg.keyfile}
${optionalString (cfg.cachedir != null) "cachedir ${cfg.cachedir}"}
${optionalString cfg.nodump "nodump"}
${optionalString cfg.printStats "print-stats"}
${optionalString cfg.printStats "humanize-numbers"}
${optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)}
${optionalString cfg.aggressiveNetworking "aggressive-networking"}
${concatStringsSep "\n" (map (v: "exclude ${v}") cfg.excludes)}
${concatStringsSep "\n" (map (v: "include ${v}") cfg.includes)}
${optionalString cfg.lowmem "lowmem"}
${optionalString cfg.verylowmem "verylowmem"}
${optionalString (cfg.maxbw != null) "maxbw ${toString cfg.maxbw}"}
${optionalString (cfg.maxbwRateUp != null) "maxbw-rate-up ${toString cfg.maxbwRateUp}"}
${optionalString (cfg.maxbwRateDown != null) "maxbw-rate-down ${toString cfg.maxbwRateDown}"}
${lib.optionalString (cfg.cachedir != null) "cachedir ${cfg.cachedir}"}
${lib.optionalString cfg.nodump "nodump"}
${lib.optionalString cfg.printStats "print-stats"}
${lib.optionalString cfg.printStats "humanize-numbers"}
${lib.optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)}
${lib.optionalString cfg.aggressiveNetworking "aggressive-networking"}
${lib.concatStringsSep "\n" (map (v: "exclude ${v}") cfg.excludes)}
${lib.concatStringsSep "\n" (map (v: "include ${v}") cfg.includes)}
${lib.optionalString cfg.lowmem "lowmem"}
${lib.optionalString cfg.verylowmem "verylowmem"}
${lib.optionalString (cfg.maxbw != null) "maxbw ${toString cfg.maxbw}"}
${lib.optionalString (cfg.maxbwRateUp != null) "maxbw-rate-up ${toString cfg.maxbwRateUp}"}
${lib.optionalString (cfg.maxbwRateDown != null) "maxbw-rate-down ${toString cfg.maxbwRateDown}"}
'';
in
{
imports = [
(mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
(lib.mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
];
options = {
services.tarsnap = {
enable = mkEnableOption "periodic tarsnap backups";
enable = lib.mkEnableOption "periodic tarsnap backups";
package = mkPackageOption pkgs "tarsnap" { };
package = lib.mkPackageOption pkgs "tarsnap" { };
keyfile = mkOption {
type = types.str;
keyfile = lib.mkOption {
type = lib.types.str;
default = "/root/tarsnap.key";
description = ''
The keyfile which associates this machine with your tarsnap
@ -61,14 +58,14 @@ in
'';
};
archives = mkOption {
type = types.attrsOf (types.submodule ({ config, options, ... }:
archives = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ config, options, ... }:
{
options = {
keyfile = mkOption {
type = types.str;
keyfile = lib.mkOption {
type = lib.types.str;
default = gcfg.keyfile;
defaultText = literalExpression "config.${opt.keyfile}";
defaultText = lib.literalExpression "config.${opt.keyfile}";
description = ''
Set a specific keyfile for this archive. This defaults to
`"/root/tarsnap.key"` if left unspecified.
@ -88,10 +85,10 @@ in
'';
};
cachedir = mkOption {
type = types.nullOr types.path;
default = "/var/cache/tarsnap/${utils.escapeSystemdPath config.keyfile}";
defaultText = literalExpression ''
cachedir = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = "/var/cache/tarsnap/${utils.lib.escapeSystemdPath config.keyfile}";
defaultText = lib.literalExpression ''
"/var/cache/tarsnap/''${utils.escapeSystemdPath config.${options.keyfile}}"
'';
description = ''
@ -106,16 +103,16 @@ in
'';
};
nodump = mkOption {
type = types.bool;
nodump = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Exclude files with the `nodump` flag.
'';
};
printStats = mkOption {
type = types.bool;
printStats = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Print global archive statistics upon completion.
@ -124,8 +121,8 @@ in
'';
};
checkpointBytes = mkOption {
type = types.nullOr types.str;
checkpointBytes = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "1GB";
description = ''
Create a checkpoint every `checkpointBytes`
@ -138,8 +135,8 @@ in
'';
};
period = mkOption {
type = types.str;
period = lib.mkOption {
type = lib.types.str;
default = "01:15";
example = "hourly";
description = ''
@ -150,8 +147,8 @@ in
'';
};
aggressiveNetworking = mkOption {
type = types.bool;
aggressiveNetworking = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Upload data over multiple TCP connections, potentially
@ -162,22 +159,22 @@ in
'';
};
directories = mkOption {
type = types.listOf types.path;
directories = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [];
description = "List of filesystem paths to archive.";
};
excludes = mkOption {
type = types.listOf types.str;
excludes = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
Exclude files and directories matching these patterns.
'';
};
includes = mkOption {
type = types.listOf types.str;
includes = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
Include only files and directories matching these
@ -187,8 +184,8 @@ in
'';
};
lowmem = mkOption {
type = types.bool;
lowmem = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Reduce memory consumption by not caching small files.
@ -198,8 +195,8 @@ in
'';
};
verylowmem = mkOption {
type = types.bool;
verylowmem = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Reduce memory consumption by a factor of 2 beyond what
@ -208,8 +205,8 @@ in
'';
};
maxbw = mkOption {
type = types.nullOr types.int;
maxbw = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = ''
Abort archival if upstream bandwidth usage in bytes
@ -217,40 +214,40 @@ in
'';
};
maxbwRateUp = mkOption {
type = types.nullOr types.int;
maxbwRateUp = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = literalExpression "25 * 1000";
example = lib.literalExpression "25 * 1000";
description = ''
Upload bandwidth rate limit in bytes.
'';
};
maxbwRateDown = mkOption {
type = types.nullOr types.int;
maxbwRateDown = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = literalExpression "50 * 1000";
example = lib.literalExpression "50 * 1000";
description = ''
Download bandwidth rate limit in bytes.
'';
};
verbose = mkOption {
type = types.bool;
verbose = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to produce verbose logging output.
'';
};
explicitSymlinks = mkOption {
type = types.bool;
explicitSymlinks = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to follow symlinks specified as archives.
'';
};
followSymlinks = mkOption {
type = types.bool;
followSymlinks = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to follow all symlinks in archive trees.
@ -262,7 +259,7 @@ in
default = {};
example = literalExpression ''
example = lib.literalExpression ''
{
nixos =
{ directories = [ "/home" "/root/ssl" ];
@ -292,19 +289,19 @@ in
};
};
config = mkIf gcfg.enable {
config = lib.mkIf gcfg.enable {
assertions =
(mapAttrsToList (name: cfg:
(lib.mapAttrsToList (name: cfg:
{ assertion = cfg.directories != [];
message = "Must specify paths for tarsnap to back up";
}) gcfg.archives) ++
(mapAttrsToList (name: cfg:
(lib.mapAttrsToList (name: cfg:
{ assertion = !(cfg.lowmem && cfg.verylowmem);
message = "You cannot set both lowmem and verylowmem";
}) gcfg.archives);
systemd.services =
(mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" {
(lib.mapAttrs' (name: cfg: lib.nameValuePair "tarsnap-${name}" {
description = "Tarsnap archive '${name}'";
requires = [ "network-online.target" ];
after = [ "network-online.target" ];
@ -322,11 +319,11 @@ in
script = let
tarsnap = ''${lib.getExe gcfg.package} --configfile "/etc/tarsnap/${name}.conf"'';
run = ''${tarsnap} -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \
${optionalString cfg.verbose "-v"} \
${optionalString cfg.explicitSymlinks "-H"} \
${optionalString cfg.followSymlinks "-L"} \
${concatStringsSep " " cfg.directories}'';
cachedir = escapeShellArg cfg.cachedir;
${lib.optionalString cfg.verbose "-v"} \
${lib.optionalString cfg.explicitSymlinks "-H"} \
${lib.optionalString cfg.followSymlinks "-L"} \
${lib.concatStringsSep " " cfg.directories}'';
cachedir = lib.escapeShellArg cfg.cachedir;
in if (cfg.cachedir != null) then ''
mkdir -p ${cachedir}
chmod 0700 ${cachedir}
@ -353,7 +350,7 @@ in
};
}) gcfg.archives) //
(mapAttrs' (name: cfg: nameValuePair "tarsnap-restore-${name}"{
(lib.mapAttrs' (name: cfg: lib.nameValuePair "tarsnap-restore-${name}"{
description = "Tarsnap restore '${name}'";
requires = [ "network-online.target" ];
@ -362,8 +359,8 @@ in
script = let
tarsnap = ''${lib.getExe gcfg.package} --configfile "/etc/tarsnap/${name}.conf"'';
lastArchive = "$(${tarsnap} --list-archives | sort | tail -1)";
run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}'';
cachedir = escapeShellArg cfg.cachedir;
run = ''${tarsnap} -x -f "${lastArchive}" ${lib.optionalString cfg.verbose "-v"}'';
cachedir = lib.escapeShellArg cfg.cachedir;
in if (cfg.cachedir != null) then ''
mkdir -p ${cachedir}
@ -393,14 +390,14 @@ in
# Note: the timer must be Persistent=true, so that systemd will start it even
# if e.g. your laptop was asleep while the latest interval occurred.
systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}"
systemd.timers = lib.mapAttrs' (name: cfg: lib.nameValuePair "tarsnap-${name}"
{ timerConfig.OnCalendar = cfg.period;
timerConfig.Persistent = "true";
wantedBy = [ "timers.target" ];
}) gcfg.archives;
environment.etc =
mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
lib.mapAttrs' (name: cfg: lib.nameValuePair "tarsnap/${name}.conf"
{ text = configFile name cfg;
}) gcfg.archives;

View File

@ -1,56 +1,53 @@
{ lib, pkgs, config, ... }:
with lib;
let
cfg = config.services.zfs.autoReplication;
recursive = optionalString cfg.recursive " --recursive";
followDelete = optionalString cfg.followDelete " --follow-delete";
recursive = lib.optionalString cfg.recursive " --recursive";
followDelete = lib.optionalString cfg.followDelete " --follow-delete";
in {
options = {
services.zfs.autoReplication = {
enable = mkEnableOption "ZFS snapshot replication";
enable = lib.mkEnableOption "ZFS snapshot replication";
followDelete = mkOption {
followDelete = lib.mkOption {
description = "Remove remote snapshots that don't have a local correspondent.";
default = true;
type = types.bool;
type = lib.types.bool;
};
host = mkOption {
host = lib.mkOption {
description = "Remote host where snapshots should be sent. `lz4` is expected to be installed on this host.";
example = "example.com";
type = types.str;
type = lib.types.str;
};
identityFilePath = mkOption {
identityFilePath = lib.mkOption {
description = "Path to SSH key used to login to host.";
example = "/home/username/.ssh/id_rsa";
type = types.path;
type = lib.types.path;
};
localFilesystem = mkOption {
localFilesystem = lib.mkOption {
description = "Local ZFS filesystem from which snapshots should be sent. Defaults to the attribute name.";
example = "pool/file/path";
type = types.str;
type = lib.types.str;
};
remoteFilesystem = mkOption {
remoteFilesystem = lib.mkOption {
description = "Remote ZFS filesystem where snapshots should be sent.";
example = "pool/file/path";
type = types.str;
type = lib.types.str;
};
recursive = mkOption {
recursive = lib.mkOption {
description = "Recursively discover snapshots to send.";
default = true;
type = types.bool;
type = lib.types.bool;
};
username = mkOption {
username = lib.mkOption {
description = "Username used by SSH to login to remote host.";
example = "username";
type = types.str;
type = lib.types.str;
};
};
};
@ -73,7 +70,7 @@ in {
"https://github.com/alunduil/zfs-replicate"
];
restartIfChanged = false;
serviceConfig.ExecStart = "${pkgs.zfs-replicate}/bin/zfs-replicate${recursive} -l ${escapeShellArg cfg.username} -i ${escapeShellArg cfg.identityFilePath}${followDelete} ${escapeShellArg cfg.host} ${escapeShellArg cfg.remoteFilesystem} ${escapeShellArg cfg.localFilesystem}";
serviceConfig.ExecStart = "${pkgs.zfs-replicate}/bin/zfs-replicate${recursive} -l ${lib.escapeShellArg cfg.username} -i ${lib.escapeShellArg cfg.identityFilePath}${followDelete} ${lib.escapeShellArg cfg.host} ${lib.escapeShellArg cfg.remoteFilesystem} ${lib.escapeShellArg cfg.localFilesystem}";
wantedBy = [
"zfs-snapshot-daily.service"
"zfs-snapshot-frequent.service"

View File

@ -1,27 +1,25 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.zrepl;
format = pkgs.formats.yaml { };
configFile = format.generate "zrepl.yml" cfg.settings;
in
{
meta.maintainers = with maintainers; [ cole-h ];
meta.maintainers = with lib.maintainers; [ cole-h ];
options = {
services.zrepl = {
enable = mkEnableOption "zrepl";
enable = lib.mkEnableOption "zrepl";
package = mkPackageOption pkgs "zrepl" { };
package = lib.mkPackageOption pkgs "zrepl" { };
settings = mkOption {
settings = lib.mkOption {
default = { };
description = ''
Configuration for zrepl. See <https://zrepl.github.io/configuration.html>
for more information.
'';
type = types.submodule {
type = lib.types.submodule {
freeformType = format.type;
};
};
@ -30,7 +28,7 @@ in
### Implementation ###
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
# zrepl looks for its config in this location by default. This

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.erigon;
@ -11,18 +9,18 @@ in {
options = {
services.erigon = {
enable = mkEnableOption "Ethereum implementation on the efficiency frontier";
enable = lib.mkEnableOption "Ethereum implementation on the efficiency frontier";
package = mkPackageOption pkgs "erigon" { };
package = lib.mkPackageOption pkgs "erigon" { };
extraArgs = mkOption {
type = types.listOf types.str;
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Additional arguments passed to Erigon";
default = [ ];
};
secretJwtPath = mkOption {
type = types.path;
secretJwtPath = lib.mkOption {
type = lib.types.path;
description = ''
Path to the secret jwt used for the http api authentication.
'';
@ -30,7 +28,7 @@ in {
example = "config.age.secrets.ERIGON_JWT.path";
};
settings = mkOption {
settings = lib.mkOption {
description = ''
Configuration for Erigon
Refer to <https://github.com/ledgerwatch/erigon#usage> for details on supported values.
@ -52,7 +50,7 @@ in {
"log.console.verbosity" = 3; # info
};
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
{
datadir = "/var/lib/erigon";
chain = "mainnet";
@ -71,20 +69,20 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
# Default values are the same as in the binary, they are just written here for convenience.
services.erigon.settings = {
datadir = mkDefault "/var/lib/erigon";
chain = mkDefault "mainnet";
http = mkDefault true;
"http.port" = mkDefault 8545;
"http.api" = mkDefault ["eth" "debug" "net" "trace" "web3" "erigon"];
ws = mkDefault true;
port = mkDefault 30303;
"authrpc.port" = mkDefault 8551;
"torrent.port" = mkDefault 42069;
"private.api.addr" = mkDefault "localhost:9090";
"log.console.verbosity" = mkDefault 3; # info
datadir = lib.mkDefault "/var/lib/erigon";
chain = lib.mkDefault "mainnet";
http = lib.mkDefault true;
"http.port" = lib.mkDefault 8545;
"http.api" = lib.mkDefault ["eth" "debug" "net" "trace" "web3" "erigon"];
ws = lib.mkDefault true;
port = lib.mkDefault 30303;
"authrpc.port" = lib.mkDefault 8551;
"torrent.port" = lib.mkDefault 42069;
"private.api.addr" = lib.mkDefault "localhost:9090";
"log.console.verbosity" = lib.mkDefault 3; # info
};
systemd.services.erigon = {

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
eachGeth = config.services.geth;
@ -11,28 +8,28 @@ let
enable = lib.mkEnableOption "Go Ethereum Node";
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 30303;
description = "Port number Go Ethereum will be listening on, both TCP and UDP.";
};
http = {
enable = lib.mkEnableOption "Go Ethereum HTTP API";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Listen address of Go Ethereum HTTP API.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 8545;
description = "Port number of Go Ethereum HTTP API.";
};
apis = mkOption {
type = types.nullOr (types.listOf types.str);
apis = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
description = "APIs to enable over WebSocket";
example = ["net" "eth"];
@ -41,20 +38,20 @@ let
websocket = {
enable = lib.mkEnableOption "Go Ethereum WebSocket API";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Listen address of Go Ethereum WebSocket API.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 8546;
description = "Port number of Go Ethereum WebSocket API.";
};
apis = mkOption {
type = types.nullOr (types.listOf types.str);
apis = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
description = "APIs to enable over WebSocket";
example = ["net" "eth"];
@ -63,27 +60,27 @@ let
authrpc = {
enable = lib.mkEnableOption "Go Ethereum Auth RPC API";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Listen address of Go Ethereum Auth RPC API.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 8551;
description = "Port number of Go Ethereum Auth RPC API.";
};
vhosts = mkOption {
type = types.nullOr (types.listOf types.str);
vhosts = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = ["localhost"];
description = "List of virtual hostnames from which to accept requests.";
example = ["localhost" "geth.example.org"];
};
jwtsecret = mkOption {
type = types.str;
jwtsecret = lib.mkOption {
type = lib.types.str;
default = "";
description = "Path to a JWT secret for authenticated RPC endpoint.";
example = "/var/run/geth/jwtsecret";
@ -92,50 +89,50 @@ let
metrics = {
enable = lib.mkEnableOption "Go Ethereum prometheus metrics";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Listen address of Go Ethereum metrics service.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 6060;
description = "Port number of Go Ethereum metrics service.";
};
};
network = mkOption {
type = types.nullOr (types.enum [ "goerli" "rinkeby" "yolov2" "ropsten" ]);
network = lib.mkOption {
type = lib.types.nullOr (lib.types.enum [ "goerli" "rinkeby" "yolov2" "ropsten" ]);
default = null;
description = "The network to connect to. Mainnet (null) is the default ethereum network.";
};
syncmode = mkOption {
type = types.enum [ "snap" "fast" "full" "light" ];
syncmode = lib.mkOption {
type = lib.types.enum [ "snap" "fast" "full" "light" ];
default = "snap";
description = "Blockchain sync mode.";
};
gcmode = mkOption {
type = types.enum [ "full" "archive" ];
gcmode = lib.mkOption {
type = lib.types.enum [ "full" "archive" ];
default = "full";
description = "Blockchain garbage collection mode.";
};
maxpeers = mkOption {
type = types.int;
maxpeers = lib.mkOption {
type = lib.types.int;
default = 50;
description = "Maximum peers to connect to.";
};
extraArgs = mkOption {
type = types.listOf types.str;
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Additional arguments passed to Go Ethereum.";
default = [];
};
package = mkPackageOption pkgs [ "go-ethereum" "geth" ] { };
package = lib.mkPackageOption pkgs [ "go-ethereum" "geth" ] { };
};
};
in
@ -145,8 +142,8 @@ in
###### interface
options = {
services.geth = mkOption {
type = types.attrsOf (types.submodule gethOpts);
services.geth = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule gethOpts);
default = {};
description = "Specification of one or more geth instances.";
};
@ -154,17 +151,17 @@ in
###### implementation
config = mkIf (eachGeth != {}) {
config = lib.mkIf (eachGeth != {}) {
environment.systemPackages = flatten (mapAttrsToList (gethName: cfg: [
environment.systemPackages = lib.flatten (lib.mapAttrsToList (gethName: cfg: [
cfg.package
]) eachGeth);
systemd.services = mapAttrs' (gethName: cfg: let
systemd.services = lib.mapAttrs' (gethName: cfg: let
stateDir = "goethereum/${gethName}/${if (cfg.network == null) then "mainnet" else cfg.network}";
dataDir = "/var/lib/${stateDir}";
in (
nameValuePair "geth-${gethName}" (mkIf cfg.enable {
lib.nameValuePair "geth-${gethName}" (lib.mkIf cfg.enable {
description = "Go Ethereum node (${gethName})";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
@ -186,16 +183,16 @@ in
${cfg.package}/bin/geth \
--nousb \
--ipcdisable \
${optionalString (cfg.network != null) ''--${cfg.network}''} \
${lib.optionalString (cfg.network != null) ''--${cfg.network}''} \
--syncmode ${cfg.syncmode} \
--gcmode ${cfg.gcmode} \
--port ${toString cfg.port} \
--maxpeers ${toString cfg.maxpeers} \
${optionalString cfg.http.enable ''--http --http.addr ${cfg.http.address} --http.port ${toString cfg.http.port}''} \
${optionalString (cfg.http.apis != null) ''--http.api ${lib.concatStringsSep "," cfg.http.apis}''} \
${optionalString cfg.websocket.enable ''--ws --ws.addr ${cfg.websocket.address} --ws.port ${toString cfg.websocket.port}''} \
${optionalString (cfg.websocket.apis != null) ''--ws.api ${lib.concatStringsSep "," cfg.websocket.apis}''} \
${optionalString cfg.metrics.enable ''--metrics --metrics.addr ${cfg.metrics.address} --metrics.port ${toString cfg.metrics.port}''} \
${lib.optionalString cfg.http.enable ''--http --http.addr ${cfg.http.address} --http.port ${toString cfg.http.port}''} \
${lib.optionalString (cfg.http.apis != null) ''--http.api ${lib.concatStringsSep "," cfg.http.apis}''} \
${lib.optionalString cfg.websocket.enable ''--ws --ws.addr ${cfg.websocket.address} --ws.port ${toString cfg.websocket.port}''} \
${lib.optionalString (cfg.websocket.apis != null) ''--ws.api ${lib.concatStringsSep "," cfg.websocket.apis}''} \
${lib.optionalString cfg.metrics.enable ''--metrics --metrics.addr ${cfg.metrics.address} --metrics.port ${toString cfg.metrics.port}''} \
--authrpc.addr ${cfg.authrpc.address} --authrpc.port ${toString cfg.authrpc.port} --authrpc.vhosts ${lib.concatStringsSep "," cfg.authrpc.vhosts} \
${if (cfg.authrpc.jwtsecret != "") then ''--authrpc.jwtsecret ${cfg.authrpc.jwtsecret}'' else ''--authrpc.jwtsecret ${dataDir}/geth/jwtsecret''} \
${lib.escapeShellArgs cfg.extraArgs} \

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.lighthouse;
@ -8,47 +6,47 @@ in {
options = {
services.lighthouse = {
beacon = mkOption {
beacon = lib.mkOption {
description = "Beacon node";
default = {};
type = types.submodule {
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption "Lightouse Beacon node";
dataDir = mkOption {
type = types.str;
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/lighthouse-beacon";
description = ''
Directory where data will be stored. Each chain will be stored under it's own specific subdirectory.
'';
};
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
description = ''
Listen address of Beacon node.
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 9000;
description = ''
Port number the Beacon node will be listening on.
'';
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Open the port in the firewall
'';
};
disableDepositContractSync = mkOption {
type = types.bool;
disableDepositContractSync = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Explicitly disables syncing of deposit logs from the execution node.
@ -58,24 +56,24 @@ in {
};
execution = {
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
Listen address for the execution layer.
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 8551;
description = ''
Port number the Beacon node will be listening on for the execution layer.
'';
};
jwtPath = mkOption {
type = types.str;
jwtPath = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Path for the jwt secret required to connect to the execution layer.
@ -85,16 +83,16 @@ in {
http = {
enable = lib.mkEnableOption "Beacon node http api";
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 5052;
description = ''
Port number of Beacon node RPC service.
'';
};
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
Listen address of Beacon node RPC service.
@ -104,16 +102,16 @@ in {
metrics = {
enable = lib.mkEnableOption "Beacon node prometheus metrics";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
Listen address of Beacon node metrics service.
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 5054;
description = ''
Port number of Beacon node metrics service.
@ -121,8 +119,8 @@ in {
};
};
extraArgs = mkOption {
type = types.str;
extraArgs = lib.mkOption {
type = lib.types.str;
description = ''
Additional arguments passed to the lighthouse beacon command.
'';
@ -133,27 +131,27 @@ in {
};
};
validator = mkOption {
validator = lib.mkOption {
description = "Validator node";
default = {};
type = types.submodule {
type = lib.types.submodule {
options = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Lightouse Validator node.";
};
dataDir = mkOption {
type = types.str;
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/lighthouse-validator";
description = ''
Directory where data will be stored. Each chain will be stored under it's own specific subdirectory.
'';
};
beaconNodes = mkOption {
type = types.listOf types.str;
beaconNodes = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = ["http://localhost:5052"];
description = ''
Beacon nodes to connect to.
@ -162,16 +160,16 @@ in {
metrics = {
enable = lib.mkEnableOption "Validator node prometheus metrics";
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
Listen address of Validator node metrics service.
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 5056;
description = ''
Port number of Validator node metrics service.
@ -179,8 +177,8 @@ in {
};
};
extraArgs = mkOption {
type = types.str;
extraArgs = lib.mkOption {
type = lib.types.str;
description = ''
Additional arguments passed to the lighthouse validator command.
'';
@ -191,16 +189,16 @@ in {
};
};
network = mkOption {
type = types.enum [ "mainnet" "gnosis" "chiado" "sepolia" "holesky" ];
network = lib.mkOption {
type = lib.types.enum [ "mainnet" "gnosis" "chiado" "sepolia" "holesky" ];
default = "mainnet";
description = ''
The network to connect to. Mainnet is the default ethereum network.
'';
};
extraArgs = mkOption {
type = types.str;
extraArgs = lib.mkOption {
type = lib.types.str;
description = ''
Additional arguments passed to every lighthouse command.
'';
@ -210,17 +208,17 @@ in {
};
};
config = mkIf (cfg.beacon.enable || cfg.validator.enable) {
config = lib.mkIf (cfg.beacon.enable || cfg.validator.enable) {
environment.systemPackages = [ pkgs.lighthouse ] ;
networking.firewall = mkIf cfg.beacon.enable {
allowedTCPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ];
allowedUDPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ];
networking.firewall = lib.mkIf cfg.beacon.enable {
allowedTCPPorts = lib.mkIf cfg.beacon.openFirewall [ cfg.beacon.port ];
allowedUDPPorts = lib.mkIf cfg.beacon.openFirewall [ cfg.beacon.port ];
};
systemd.services.lighthouse-beacon = mkIf cfg.beacon.enable {
systemd.services.lighthouse-beacon = lib.mkIf cfg.beacon.enable {
description = "Lighthouse beacon node (connect to P2P nodes and verify blocks)";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
@ -268,7 +266,7 @@ in {
};
};
systemd.services.lighthouse-validator = mkIf cfg.validator.enable {
systemd.services.lighthouse-validator = lib.mkIf cfg.validator.enable {
description = "Lighthouse validtor node (manages validators, using data obtained from the beacon node via a HTTP API)";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
@ -281,7 +279,7 @@ in {
--network ${cfg.network} \
--beacon-nodes ${lib.concatStringsSep "," cfg.validator.beaconNodes} \
--datadir ${cfg.validator.dataDir}/${cfg.network} \
${optionalString cfg.validator.metrics.enable ''--metrics --metrics-address ${cfg.validator.metrics.address} --metrics-port ${toString cfg.validator.metrics.port}''} \
${lib.optionalString cfg.validator.metrics.enable ''--metrics --metrics-address ${cfg.validator.metrics.address} --metrics-port ${toString cfg.validator.metrics.port}''} \
${cfg.extraArgs} ${cfg.validator.extraArgs}
'';

View File

@ -4,8 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.k3s;
removeOption =
@ -98,7 +96,7 @@ let
}
);
enabledManifests = with builtins; filter (m: m.enable) (attrValues cfg.manifests);
enabledManifests = lib.filter (m: m.enable) (lib.attrValues cfg.manifests);
linkManifestEntry = m: "${pkgs.coreutils-full}/bin/ln -sfn ${m.source} ${manifestDir}/${m.target}";
linkImageEntry = image: "${pkgs.coreutils-full}/bin/ln -sfn ${image} ${imageDir}/${image.name}";
linkChartEntry =
@ -132,11 +130,11 @@ in
# interface
options.services.k3s = {
enable = mkEnableOption "k3s";
enable = lib.mkEnableOption "k3s";
package = mkPackageOption pkgs "k3s" { };
package = lib.mkPackageOption pkgs "k3s" { };
role = mkOption {
role = lib.mkOption {
description = ''
Whether k3s should run as a server or agent.
@ -152,14 +150,14 @@ in
- `serverAddr` is required.
'';
default = "server";
type = types.enum [
type = lib.types.enum [
"server"
"agent"
];
};
serverAddr = mkOption {
type = types.str;
serverAddr = lib.mkOption {
type = lib.types.str;
description = ''
The k3s server to connect to.
@ -171,8 +169,8 @@ in
default = "";
};
clusterInit = mkOption {
type = types.bool;
clusterInit = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Initialize HA cluster using an embedded etcd datastore.
@ -193,8 +191,8 @@ in
'';
};
token = mkOption {
type = types.str;
token = lib.mkOption {
type = lib.types.str;
description = ''
The k3s token to use when connecting to a server.
@ -204,15 +202,15 @@ in
default = "";
};
tokenFile = mkOption {
type = types.nullOr types.path;
tokenFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "File path containing k3s token to use when connecting to the server.";
default = null;
};
extraFlags = mkOption {
extraFlags = lib.mkOption {
description = "Extra flags to pass to the k3s command.";
type = with types; either str (listOf str);
type = with lib.types; either str (listOf str);
default = [ ];
example = [
"--no-deploy traefik"
@ -220,28 +218,28 @@ in
];
};
disableAgent = mkOption {
type = types.bool;
disableAgent = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Only run the server. This option only makes sense for a server.";
};
environmentFile = mkOption {
type = types.nullOr types.path;
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = ''
File path containing environment variables for configuring the k3s service in the format of an EnvironmentFile. See systemd.exec(5).
'';
default = null;
};
configPath = mkOption {
type = types.nullOr types.path;
configPath = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "File path containing the k3s YAML config. This is useful when the config is generated (for example on boot).";
};
manifests = mkOption {
type = types.attrsOf manifestModule;
manifests = lib.mkOption {
type = lib.types.attrsOf manifestModule;
default = { };
example = lib.literalExpression ''
deployment.source = ../manifests/deployment.yaml;
@ -328,8 +326,8 @@ in
'';
};
charts = mkOption {
type = with types; attrsOf (either path package);
charts = lib.mkOption {
type = with lib.types; attrsOf (either path package);
default = { };
example = lib.literalExpression ''
nginx = ../charts/my-nginx-chart.tgz;
@ -346,8 +344,8 @@ in
'';
};
containerdConfigTemplate = mkOption {
type = types.nullOr types.str;
containerdConfigTemplate = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = lib.literalExpression ''
# Base K3s config
@ -366,8 +364,8 @@ in
'';
};
images = mkOption {
type = with types; listOf package;
images = lib.mkOption {
type = with lib.types; listOf package;
default = [ ];
example = lib.literalExpression ''
[
@ -440,7 +438,7 @@ in
# implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
warnings =
(lib.optional (cfg.role != "server" && cfg.manifests != { })
"k3s: Auto deploying manifests are only installed on server nodes (role == server), they will be ignored by this node."
@ -500,7 +498,7 @@ in
"network-online.target"
];
wantedBy = [ "multi-user.target" ];
path = optional config.boot.zfs.enabled config.boot.zfs.package;
path = lib.optional config.boot.zfs.enabled config.boot.zfs.package;
serviceConfig = {
# See: https://github.com/rancher/k3s/blob/dddbd16305284ae4bd14c0aade892412310d7edc/install.sh#L197
Type = if cfg.role == "agent" then "exec" else "notify";
@ -514,15 +512,15 @@ in
TasksMax = "infinity";
EnvironmentFile = cfg.environmentFile;
ExecStartPre = activateK3sContent;
ExecStart = concatStringsSep " \\\n " (
ExecStart = lib.concatStringsSep " \\\n " (
[ "${cfg.package}/bin/k3s ${cfg.role}" ]
++ (optional cfg.clusterInit "--cluster-init")
++ (optional cfg.disableAgent "--disable-agent")
++ (optional (cfg.serverAddr != "") "--server ${cfg.serverAddr}")
++ (optional (cfg.token != "") "--token ${cfg.token}")
++ (optional (cfg.tokenFile != null) "--token-file ${cfg.tokenFile}")
++ (optional (cfg.configPath != null) "--config ${cfg.configPath}")
++ (optional (kubeletParams != { }) "--kubelet-arg=config=${kubeletConfig}")
++ (lib.optional cfg.clusterInit "--cluster-init")
++ (lib.optional cfg.disableAgent "--disable-agent")
++ (lib.optional (cfg.serverAddr != "") "--server ${cfg.serverAddr}")
++ (lib.optional (cfg.token != "") "--token ${cfg.token}")
++ (lib.optional (cfg.tokenFile != null) "--token-file ${cfg.tokenFile}")
++ (lib.optional (cfg.configPath != null) "--config ${cfg.configPath}")
++ (lib.optional (kubeletParams != { }) "--kubelet-arg=config=${kubeletConfig}")
++ (lib.flatten cfg.extraFlags)
);
};

View File

@ -1,7 +1,4 @@
{ config, options, pkgs, lib, ... }:
with lib;
let
version = "1.10.1";
cfg = config.services.kubernetes.addons.dns;
@ -12,37 +9,37 @@ let
};
in {
options.services.kubernetes.addons.dns = {
enable = mkEnableOption "kubernetes dns addon";
enable = lib.mkEnableOption "kubernetes dns addon";
clusterIp = mkOption {
clusterIp = lib.mkOption {
description = "Dns addon clusterIP";
# this default is also what kubernetes users
default = (
concatStringsSep "." (
take 3 (splitString "." config.services.kubernetes.apiserver.serviceClusterIpRange
lib.concatStringsSep "." (
lib.take 3 (lib.splitString "." config.services.kubernetes.apiserver.serviceClusterIpRange
))
) + ".254";
defaultText = literalMD ''
defaultText = lib.literalMD ''
The `x.y.z.254` IP of
`config.${options.services.kubernetes.apiserver.serviceClusterIpRange}`.
'';
type = types.str;
type = lib.types.str;
};
clusterDomain = mkOption {
clusterDomain = lib.mkOption {
description = "Dns cluster domain";
default = "cluster.local";
type = types.str;
type = lib.types.str;
};
replicas = mkOption {
replicas = lib.mkOption {
description = "Number of DNS pod replicas to deploy in the cluster.";
default = 2;
type = types.int;
type = lib.types.int;
};
reconcileMode = mkOption {
reconcileMode = lib.mkOption {
description = ''
Controls the addon manager reconciliation mode for the DNS addon.
@ -51,12 +48,12 @@ in {
See: <https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/addon-manager/README.md>.
'';
default = "Reconcile";
type = types.enum [ "Reconcile" "EnsureExists" ];
type = lib.types.enum [ "Reconcile" "EnsureExists" ];
};
coredns = mkOption {
coredns = lib.mkOption {
description = "Docker image to seed for the CoreDNS container.";
type = types.attrs;
type = lib.types.attrs;
default = {
imageName = "coredns/coredns";
imageDigest = "sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e";
@ -65,13 +62,13 @@ in {
};
};
corefile = mkOption {
corefile = lib.mkOption {
description = ''
Custom coredns corefile configuration.
See: <https://coredns.io/manual/toc/#configuration>.
'';
type = types.str;
type = lib.types.str;
default = ''
.:${toString ports.dns} {
errors
@ -87,7 +84,7 @@ in {
reload
loadbalance
}'';
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
'''
.:${toString ports.dns} {
errors
@ -108,9 +105,9 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.kubernetes.kubelet.seedDockerImages =
singleton (pkgs.dockerTools.pullImage cfg.coredns);
lib.singleton (pkgs.dockerTools.pullImage cfg.coredns);
services.kubernetes.addonManager.bootstrapAddons = {
coredns-cr = {
@ -366,7 +363,7 @@ in {
};
};
services.kubernetes.kubelet.clusterDns = mkDefault [ cfg.clusterIp ];
services.kubernetes.kubelet.clusterDns = lib.mkDefault [ cfg.clusterIp ];
};
meta.buildDocsInSandbox = false;

View File

@ -1,19 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.pacemaker;
in
{
# interface
options.services.pacemaker = {
enable = mkEnableOption "pacemaker";
enable = lib.mkEnableOption "pacemaker";
package = mkPackageOption pkgs "pacemaker" { };
package = lib.mkPackageOption pkgs "pacemaker" { };
};
# implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [ {
assertion = config.services.corosync.enable;
message = ''

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.patroni;
defaultUser = "patroni";
@ -21,20 +20,20 @@ in
options.services.patroni = {
enable = mkEnableOption "Patroni";
enable = lib.mkEnableOption "Patroni";
postgresqlPackage = mkOption {
type = types.package;
example = literalExpression "pkgs.postgresql_14";
postgresqlPackage = lib.mkOption {
type = lib.types.package;
example = lib.literalExpression "pkgs.postgresql_14";
description = ''
PostgreSQL package to use.
Plugins can be enabled like this `pkgs.postgresql_14.withPackages (p: [ p.pg_safeupdate p.postgis ])`.
'';
};
postgresqlDataDir = mkOption {
type = types.path;
defaultText = literalExpression ''"/var/lib/postgresql/''${config.services.patroni.postgresqlPackage.psqlSchema}"'';
postgresqlDataDir = lib.mkOption {
type = lib.types.path;
defaultText = lib.literalExpression ''"/var/lib/postgresql/''${config.services.patroni.postgresqlPackage.psqlSchema}"'';
example = "/var/lib/postgresql/14";
default = "/var/lib/postgresql/${cfg.postgresqlPackage.psqlSchema}";
description = ''
@ -45,16 +44,16 @@ in
'';
};
postgresqlPort = mkOption {
type = types.port;
postgresqlPort = lib.mkOption {
type = lib.types.port;
default = 5432;
description = ''
The port on which PostgreSQL listens.
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = defaultUser;
example = "postgres";
description = ''
@ -63,8 +62,8 @@ in
'';
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = defaultGroup;
example = "postgres";
description = ''
@ -73,64 +72,64 @@ in
'';
};
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/patroni";
description = ''
Folder where Patroni data will be written, this is where the pgpass password file will be written.
'';
};
scope = mkOption {
type = types.str;
scope = lib.mkOption {
type = lib.types.str;
example = "cluster1";
description = ''
Cluster name.
'';
};
name = mkOption {
type = types.str;
name = lib.mkOption {
type = lib.types.str;
example = "node1";
description = ''
The name of the host. Must be unique for the cluster.
'';
};
namespace = mkOption {
type = types.str;
namespace = lib.mkOption {
type = lib.types.str;
default = "/service";
description = ''
Path within the configuration store where Patroni will keep information about the cluster.
'';
};
nodeIp = mkOption {
type = types.str;
nodeIp = lib.mkOption {
type = lib.types.str;
example = "192.168.1.1";
description = ''
IP address of this node.
'';
};
otherNodesIps = mkOption {
type = types.listOf types.str;
otherNodesIps = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ "192.168.1.2" "192.168.1.3" ];
description = ''
IP addresses of the other nodes.
'';
};
restApiPort = mkOption {
type = types.port;
restApiPort = lib.mkOption {
type = lib.types.port;
default = 8008;
description = ''
The port on Patroni's REST api listens.
'';
};
softwareWatchdog = mkOption {
type = types.bool;
softwareWatchdog = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
This will configure Patroni to use the software watchdog built into the Linux kernel
@ -138,7 +137,7 @@ in
'';
};
settings = mkOption {
settings = lib.mkOption {
type = format.type;
default = { };
description = ''
@ -148,8 +147,8 @@ in
'';
};
environmentFiles = mkOption {
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
environmentFiles = lib.mkOption {
type = with lib.types; attrsOf (nullOr (oneOf [ str path package ]));
default = { };
example = {
PATRONI_REPLICATION_PASSWORD = "/secret/file";
@ -159,7 +158,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.patroni.settings = {
scope = cfg.scope;
@ -179,7 +178,7 @@ in
pgpass = "${cfg.dataDir}/pgpass";
};
watchdog = mkIf cfg.softwareWatchdog {
watchdog = lib.mkIf cfg.softwareWatchdog {
mode = "required";
device = "/dev/watchdog";
safety_margin = 5;
@ -188,13 +187,13 @@ in
users = {
users = mkIf (cfg.user == defaultUser) {
users = lib.mkIf (cfg.user == defaultUser) {
patroni = {
group = cfg.group;
isSystemUser = true;
};
};
groups = mkIf (cfg.group == defaultGroup) {
groups = lib.mkIf (cfg.group == defaultGroup) {
patroni = { };
};
};
@ -207,11 +206,11 @@ in
after = [ "network.target" ];
script = ''
${concatStringsSep "\n" (attrValues (mapAttrs (name: path: ''export ${name}="$(< ${escapeShellArg path})"'') cfg.environmentFiles))}
${lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs (name: path: ''export ${name}="$(< ${lib.escapeShellArg path})"'') cfg.environmentFiles))}
exec ${pkgs.patroni}/bin/patroni ${configFile}
'';
serviceConfig = mkMerge [
serviceConfig = lib.mkMerge [
{
User = cfg.user;
Group = cfg.group;
@ -221,7 +220,7 @@ in
ExecReload = "${pkgs.coreutils}/bin/kill -s HUP $MAINPID";
KillMode = "process";
}
(mkIf (cfg.postgresqlDataDir == "/var/lib/postgresql/${cfg.postgresqlPackage.psqlSchema}" && cfg.dataDir == "/var/lib/patroni") {
(lib.mkIf (cfg.postgresqlDataDir == "/var/lib/postgresql/${cfg.postgresqlPackage.psqlSchema}" && cfg.dataDir == "/var/lib/patroni") {
StateDirectory = "patroni postgresql postgresql/${cfg.postgresqlPackage.psqlSchema}";
StateDirectoryMode = "0750";
})
@ -229,9 +228,9 @@ in
};
};
boot.kernelModules = mkIf cfg.softwareWatchdog [ "softdog" ];
boot.kernelModules = lib.mkIf cfg.softwareWatchdog [ "softdog" ];
services.udev.extraRules = mkIf cfg.softwareWatchdog ''
services.udev.extraRules = lib.mkIf cfg.softwareWatchdog ''
KERNEL=="watchdog", OWNER="${cfg.user}", GROUP="${cfg.group}", MODE="0600"
'';
@ -247,5 +246,5 @@ in
};
};
meta.maintainers = [ maintainers.phfroidmont ];
meta.maintainers = [ lib.maintainers.phfroidmont ];
}

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rke2;
in
@ -8,12 +6,12 @@ in
imports = [ ];
options.services.rke2 = {
enable = mkEnableOption "rke2";
enable = lib.mkEnableOption "rke2";
package = mkPackageOption pkgs "rke2" { };
package = lib.mkPackageOption pkgs "rke2" { };
role = mkOption {
type = types.enum [ "server" "agent" ];
role = lib.mkOption {
type = lib.types.enum [ "server" "agent" ];
description = ''
Whether rke2 should run as a server or agent.
@ -31,26 +29,26 @@ in
default = "server";
};
configPath = mkOption {
type = types.path;
configPath = lib.mkOption {
type = lib.types.path;
description = "Load configuration from FILE.";
default = "/etc/rancher/rke2/config.yaml";
};
debug = mkOption {
type = types.bool;
debug = lib.mkOption {
type = lib.types.bool;
description = "Turn on debug logs.";
default = false;
};
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
description = "The folder to hold state in.";
default = "/var/lib/rancher/rke2";
};
token = mkOption {
type = types.str;
token = lib.mkOption {
type = lib.types.str;
description = ''
Shared secret used to join a server or agent to a cluster.
@ -60,44 +58,44 @@ in
default = "";
};
tokenFile = mkOption {
type = types.nullOr types.path;
tokenFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "File path containing rke2 token to use when connecting to the server.";
default = null;
};
disable = mkOption {
type = types.listOf types.str;
disable = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Do not deploy packaged components and delete any deployed components.";
default = [ ];
};
nodeName = mkOption {
type = types.nullOr types.str;
nodeName = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Node name.";
default = null;
};
nodeLabel = mkOption {
type = types.listOf types.str;
nodeLabel = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Registering and starting kubelet with set of labels.";
default = [ ];
};
nodeTaint = mkOption {
type = types.listOf types.str;
nodeTaint = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Registering kubelet with set of taints.";
default = [ ];
};
nodeIP = mkOption {
type = types.nullOr types.str;
nodeIP = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "IPv4/IPv6 addresses to advertise for node.";
default = null;
};
agentToken = mkOption {
type = types.str;
agentToken = lib.mkOption {
type = lib.types.str;
description = ''
Shared secret used to join agents to the cluster, but not servers.
@ -107,27 +105,27 @@ in
default = "";
};
agentTokenFile = mkOption {
type = types.nullOr types.path;
agentTokenFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "File path containing rke2 agent token to use when connecting to the server.";
default = null;
};
serverAddr = mkOption {
type = types.str;
serverAddr = lib.mkOption {
type = lib.types.str;
description = "The rke2 server to connect to, used to join a cluster.";
example = "https://10.0.0.10:6443";
default = "";
};
selinux = mkOption {
type = types.bool;
selinux = lib.mkOption {
type = lib.types.bool;
description = "Enable SELinux in containerd.";
default = false;
};
cni = mkOption {
type = types.enum [ "none" "canal" "cilium" "calico" "flannel" ];
cni = lib.mkOption {
type = lib.types.enum [ "none" "canal" "cilium" "calico" "flannel" ];
description = ''
CNI Plugins to deploy, one of `none`, `calico`, `canal`, `cilium` or `flannel`.
@ -141,8 +139,8 @@ in
default = "canal";
};
cisHardening = mkOption {
type = types.bool;
cisHardening = lib.mkOption {
type = lib.types.bool;
description = ''
Enable CIS Hardening for RKE2.
@ -162,8 +160,8 @@ in
default = false;
};
extraFlags = mkOption {
type = types.listOf types.str;
extraFlags = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Extra flags to pass to the rke2 service/agent.
@ -176,8 +174,8 @@ in
default = [ ];
};
environmentVars = mkOption {
type = types.attrsOf types.str;
environmentVars = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = ''
Environment variables for configuring the rke2 service/agent.
@ -199,7 +197,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.role == "agent" -> (builtins.pathExists cfg.configPath || cfg.serverAddr != "");
@ -234,7 +232,7 @@ in
'';
};
# See: https://docs.rke2.io/security/hardening_guide#set-kernel-parameters
boot.kernel.sysctl = mkIf cfg.cisHardening {
boot.kernel.sysctl = lib.mkIf cfg.cisHardening {
"vm.panic_on_oom" = 0;
"vm.overcommit_memory" = 1;
"kernel.panic" = 10;
@ -254,7 +252,7 @@ in
"-/etc/sysconfig/%N"
"-/usr/local/lib/systemd/system/%N.env"
];
Environment = mapAttrsToList (k: v: "${k}=${v}") cfg.environmentVars;
Environment = lib.mapAttrsToList (k: v: "${k}=${v}") cfg.environmentVars;
KillMode = "process";
Delegate = "yes";
LimitNOFILE = 1048576;
@ -277,23 +275,23 @@ in
"-${pkgs.kmod}/bin/modprobe br_netfilter"
"-${pkgs.kmod}/bin/modprobe overlay"
];
ExecStart = "${cfg.package}/bin/rke2 '${cfg.role}' ${escapeShellArgs (
(optional (cfg.configPath != "/etc/rancher/rke2/config.yaml") "--config=${cfg.configPath}")
++ (optional cfg.debug "--debug")
++ (optional (cfg.dataDir != "/var/lib/rancher/rke2") "--data-dir=${cfg.dataDir}")
++ (optional (cfg.token != "") "--token=${cfg.token}")
++ (optional (cfg.tokenFile != null) "--token-file=${cfg.tokenFile}")
++ (optionals (cfg.role == "server" && cfg.disable != [ ]) (map (d: "--disable=${d}") cfg.disable))
++ (optional (cfg.nodeName != null) "--node-name=${cfg.nodeName}")
++ (optionals (cfg.nodeLabel != [ ]) (map (l: "--node-label=${l}") cfg.nodeLabel))
++ (optionals (cfg.nodeTaint != [ ]) (map (t: "--node-taint=${t}") cfg.nodeTaint))
++ (optional (cfg.nodeIP != null) "--node-ip=${cfg.nodeIP}")
++ (optional (cfg.role == "server" && cfg.agentToken != "") "--agent-token=${cfg.agentToken}")
++ (optional (cfg.role == "server" && cfg.agentTokenFile != null) "--agent-token-file=${cfg.agentTokenFile}")
++ (optional (cfg.serverAddr != "") "--server=${cfg.serverAddr}")
++ (optional cfg.selinux "--selinux")
++ (optional (cfg.role == "server" && cfg.cni != "canal") "--cni=${cfg.cni}")
++ (optional cfg.cisHardening "--profile=${if cfg.package.version >= "1.25" then "cis-1.23" else "cis-1.6"}")
ExecStart = "${cfg.package}/bin/rke2 '${cfg.role}' ${lib.escapeShellArgs (
(lib.optional (cfg.configPath != "/etc/rancher/rke2/config.yaml") "--config=${cfg.configPath}")
++ (lib.optional cfg.debug "--debug")
++ (lib.optional (cfg.dataDir != "/var/lib/rancher/rke2") "--data-dir=${cfg.dataDir}")
++ (lib.optional (cfg.token != "") "--token=${cfg.token}")
++ (lib.optional (cfg.tokenFile != null) "--token-file=${cfg.tokenFile}")
++ (lib.optionals (cfg.role == "server" && cfg.disable != [ ]) (map (d: "--disable=${d}") cfg.disable))
++ (lib.optional (cfg.nodeName != null) "--node-name=${cfg.nodeName}")
++ (lib.optionals (cfg.nodeLabel != [ ]) (map (l: "--node-label=${l}") cfg.nodeLabel))
++ (lib.optionals (cfg.nodeTaint != [ ]) (map (t: "--node-taint=${t}") cfg.nodeTaint))
++ (lib.optional (cfg.nodeIP != null) "--node-ip=${cfg.nodeIP}")
++ (lib.optional (cfg.role == "server" && cfg.agentToken != "") "--agent-token=${cfg.agentToken}")
++ (lib.optional (cfg.role == "server" && cfg.agentTokenFile != null) "--agent-token-file=${cfg.agentTokenFile}")
++ (lib.optional (cfg.serverAddr != "") "--server=${cfg.serverAddr}")
++ (lib.optional cfg.selinux "--selinux")
++ (lib.optional (cfg.role == "server" && cfg.cni != "canal") "--cni=${cfg.cni}")
++ (lib.optional cfg.cisHardening "--profile=${if cfg.package.version >= "1.25" then "cis-1.23" else "cis-1.6"}")
++ cfg.extraFlags
)}";
ExecStopPost = let

View File

@ -2,20 +2,19 @@
let
cfg = config.services.spark;
in
with lib;
{
options = {
services.spark = {
master = {
enable = mkEnableOption "Spark master service";
bind = mkOption {
type = types.str;
enable = lib.mkEnableOption "Spark master service";
bind = lib.mkOption {
type = lib.types.str;
description = "Address the spark master binds to.";
default = "127.0.0.1";
example = "0.0.0.0";
};
restartIfChanged = mkOption {
type = types.bool;
restartIfChanged = lib.mkOption {
type = lib.types.bool;
description = ''
Automatically restart master service on config change.
This can be set to false to defer restarts on clusters running critical applications.
@ -24,8 +23,8 @@ with lib;
'';
default = true;
};
extraEnvironment = mkOption {
type = types.attrsOf types.str;
extraEnvironment = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = "Extra environment variables to pass to spark master. See spark-standalone documentation.";
default = {};
example = {
@ -35,19 +34,19 @@ with lib;
};
};
worker = {
enable = mkEnableOption "Spark worker service";
workDir = mkOption {
type = types.path;
enable = lib.mkEnableOption "Spark worker service";
workDir = lib.mkOption {
type = lib.types.path;
description = "Spark worker work dir.";
default = "/var/lib/spark";
};
master = mkOption {
type = types.str;
master = lib.mkOption {
type = lib.types.str;
description = "Address of the spark master.";
default = "127.0.0.1:7077";
};
restartIfChanged = mkOption {
type = types.bool;
restartIfChanged = lib.mkOption {
type = lib.types.bool;
description = ''
Automatically restart worker service on config change.
This can be set to false to defer restarts on clusters running critical applications.
@ -56,8 +55,8 @@ with lib;
'';
default = true;
};
extraEnvironment = mkOption {
type = types.attrsOf types.str;
extraEnvironment = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = "Extra environment variables to pass to spark worker.";
default = {};
example = {
@ -66,18 +65,18 @@ with lib;
};
};
};
confDir = mkOption {
type = types.path;
confDir = lib.mkOption {
type = lib.types.path;
description = "Spark configuration directory. Spark will use the configuration files (spark-defaults.conf, spark-env.sh, log4j.properties, etc) from this directory.";
default = "${cfg.package}/conf";
defaultText = literalExpression ''"''${package}/conf"'';
defaultText = lib.literalExpression ''"''${package}/conf"'';
};
logDir = mkOption {
type = types.path;
logDir = lib.mkOption {
type = lib.types.path;
description = "Spark log directory.";
default = "/var/log/spark";
};
package = mkPackageOption pkgs "spark" {
package = lib.mkPackageOption pkgs "spark" {
example = ''
spark.overrideAttrs (super: rec {
pname = "spark";

View File

@ -1,10 +1,7 @@
{config, lib, pkgs, ...}:
with lib;
let
cfg = config.services.boinc;
allowRemoteGuiRpcFlag = optionalString cfg.allowRemoteGuiRpc "--allow_remote_gui_rpc";
allowRemoteGuiRpcFlag = lib.optionalString cfg.allowRemoteGuiRpc "--allow_remote_gui_rpc";
fhsEnv = pkgs.buildFHSEnv {
name = "boinc-fhs-env";
@ -16,8 +13,8 @@ let
in
{
options.services.boinc = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the BOINC distributed computing client. If this
@ -27,20 +24,20 @@ in
'';
};
package = mkPackageOption pkgs "boinc" {
package = lib.mkPackageOption pkgs "boinc" {
example = "boinc-headless";
};
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/boinc";
description = ''
The directory in which to store BOINC's configuration and data files.
'';
};
allowRemoteGuiRpc = mkOption {
type = types.bool;
allowRemoteGuiRpc = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
If set to true, any remote host can connect to and control this BOINC
@ -52,10 +49,10 @@ in
'';
};
extraEnvPackages = mkOption {
type = types.listOf types.package;
extraEnvPackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
example = literalExpression "[ pkgs.virtualbox ]";
example = lib.literalExpression "[ pkgs.virtualbox ]";
description = ''
Additional packages to make available in the environment in which
BOINC will run. Common choices are:
@ -77,7 +74,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [cfg.package];
users.users.boinc = {

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.foldingathome;
@ -11,19 +10,19 @@ let
in
{
imports = [
(mkRenamedOptionModule [ "services" "foldingAtHome" ] [ "services" "foldingathome" ])
(mkRenamedOptionModule [ "services" "foldingathome" "nickname" ] [ "services" "foldingathome" "user" ])
(mkRemovedOptionModule [ "services" "foldingathome" "config" ] ''
(lib.mkRenamedOptionModule [ "services" "foldingAtHome" ] [ "services" "foldingathome" ])
(lib.mkRenamedOptionModule [ "services" "foldingathome" "nickname" ] [ "services" "foldingathome" "user" ])
(lib.mkRemovedOptionModule [ "services" "foldingathome" "config" ] ''
Use <literal>services.foldingathome.extraArgs instead<literal>
'')
];
options.services.foldingathome = {
enable = mkEnableOption "Folding@home client";
enable = lib.mkEnableOption "Folding@home client";
package = mkPackageOption pkgs "fahclient" { };
package = lib.mkPackageOption pkgs "fahclient" { };
user = mkOption {
type = types.nullOr types.str;
user = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The user associated with the reported computation results. This will
@ -31,8 +30,8 @@ in
'';
};
team = mkOption {
type = types.int;
team = lib.mkOption {
type = lib.types.int;
default = 236565;
description = ''
The team ID associated with the reported computation results. This
@ -42,8 +41,8 @@ in
'';
};
daemonNiceLevel = mkOption {
type = types.ints.between (-20) 19;
daemonNiceLevel = lib.mkOption {
type = lib.types.ints.between (-20) 19;
default = 0;
description = ''
Daemon process priority for FAHClient.
@ -51,8 +50,8 @@ in
'';
};
extraArgs = mkOption {
type = types.listOf types.str;
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
Extra startup options for the FAHClient. Run
@ -61,7 +60,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.foldingathome = {
description = "Folding@home client";
after = [ "network.target" ];

View File

@ -1,7 +1,4 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.slurm;
@ -15,8 +12,8 @@ let
ClusterName=${cfg.clusterName}
StateSaveLocation=${cfg.stateSaveLocation}
SlurmUser=${cfg.user}
${optionalString (cfg.controlMachine != null) "controlMachine=${cfg.controlMachine}"}
${optionalString (cfg.controlAddr != null) "controlAddr=${cfg.controlAddr}"}
${lib.optionalString (cfg.controlMachine != null) "controlMachine=${cfg.controlMachine}"}
${lib.optionalString (cfg.controlAddr != null) "controlAddr=${cfg.controlAddr}"}
${toString (map (x: "NodeName=${x}\n") cfg.nodeName)}
${toString (map (x: "PartitionName=${x}\n") cfg.partitionName)}
PlugStackConfig=${plugStackConfig}/plugstack.conf
@ -26,7 +23,7 @@ let
plugStackConfig = pkgs.writeTextDir "plugstack.conf"
''
${optionalString cfg.enableSrunX11 "optional ${pkgs.slurm-spank-x11}/lib/x11.so"}
${lib.optionalString cfg.enableSrunX11 "optional ${pkgs.slurm-spank-x11}/lib/x11.so"}
${cfg.extraPlugstackConfig}
'';
@ -56,15 +53,15 @@ in
###### interface
meta.maintainers = [ maintainers.markuskowa ];
meta.maintainers = [ lib.maintainers.markuskowa ];
options = {
services.slurm = {
server = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the slurm control daemon.
@ -76,29 +73,29 @@ in
};
dbdserver = {
enable = mkEnableOption "SlurmDBD service";
enable = lib.mkEnableOption "SlurmDBD service";
dbdHost = mkOption {
type = types.str;
dbdHost = lib.mkOption {
type = lib.types.str;
default = config.networking.hostName;
defaultText = literalExpression "config.networking.hostName";
defaultText = lib.literalExpression "config.networking.hostName";
description = ''
Hostname of the machine where `slurmdbd`
is running (i.e. name returned by `hostname -s`).
'';
};
storageUser = mkOption {
type = types.str;
storageUser = lib.mkOption {
type = lib.types.str;
default = cfg.user;
defaultText = literalExpression "config.${opt.user}";
defaultText = lib.literalExpression "config.${opt.user}";
description = ''
Database user name.
'';
};
storagePassFile = mkOption {
type = with types; nullOr str;
storagePassFile = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Path to file with database password. The content of this will be used to
@ -106,8 +103,8 @@ in
'';
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra configuration for `slurmdbd.conf` See also:
@ -117,11 +114,11 @@ in
};
client = {
enable = mkEnableOption "slurm client daemon";
enable = lib.mkEnableOption "slurm client daemon";
};
enableStools = mkOption {
type = types.bool;
enableStools = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to provide a slurm.conf file.
@ -131,14 +128,14 @@ in
'';
};
package = mkPackageOption pkgs "slurm" {
package = lib.mkPackageOption pkgs "slurm" {
example = "slurm-full";
} // {
default = pkgs.slurm.override { enableX11 = ! cfg.enableSrunX11; };
};
controlMachine = mkOption {
type = types.nullOr types.str;
controlMachine = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = null;
description = ''
@ -148,10 +145,10 @@ in
'';
};
controlAddr = mkOption {
type = types.nullOr types.str;
controlAddr = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = cfg.controlMachine;
defaultText = literalExpression "config.${opt.controlMachine}";
defaultText = lib.literalExpression "config.${opt.controlMachine}";
example = null;
description = ''
Name that ControlMachine should be referred to in establishing a
@ -159,8 +156,8 @@ in
'';
};
clusterName = mkOption {
type = types.str;
clusterName = lib.mkOption {
type = lib.types.str;
default = "default";
example = "myCluster";
description = ''
@ -168,10 +165,10 @@ in
'';
};
nodeName = mkOption {
type = types.listOf types.str;
nodeName = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = literalExpression ''[ "linux[1-32] CPUs=1 State=UNKNOWN" ];'';
example = lib.literalExpression ''[ "linux[1-32] CPUs=1 State=UNKNOWN" ];'';
description = ''
Name that SLURM uses to refer to a node (or base partition for BlueGene
systems). Typically this would be the string that "/bin/hostname -s"
@ -179,19 +176,19 @@ in
'';
};
partitionName = mkOption {
type = types.listOf types.str;
partitionName = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = literalExpression ''[ "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP" ];'';
example = lib.literalExpression ''[ "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP" ];'';
description = ''
Name by which the partition may be referenced. Note that now you have
to write the partition's parameters after the name.
'';
};
enableSrunX11 = mkOption {
enableSrunX11 = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
If enabled srun will accept the option "--x11" to allow for X11 forwarding
from within an interactive session or a batch job. This activates the
@ -207,8 +204,8 @@ in
'';
};
procTrackType = mkOption {
type = types.str;
procTrackType = lib.mkOption {
type = lib.types.str;
default = "proctrack/linuxproc";
description = ''
Plugin to be used for process tracking on a job step basis.
@ -217,16 +214,16 @@ in
'';
};
stateSaveLocation = mkOption {
type = types.str;
stateSaveLocation = lib.mkOption {
type = lib.types.str;
default = "/var/spool/slurmctld";
description = ''
Directory into which the Slurm controller, slurmctld, saves its state.
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = defaultUser;
description = ''
Set this option when you want to run the slurmctld daemon
@ -236,34 +233,34 @@ in
'';
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Extra configuration options that will be added verbatim at
the end of the slurm configuration file.
'';
};
extraPlugstackConfig = mkOption {
extraPlugstackConfig = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Extra configuration that will be added to the end of `plugstack.conf`.
'';
};
extraCgroupConfig = mkOption {
extraCgroupConfig = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Extra configuration for `cgroup.conf`. This file is
used when `procTrackType=proctrack/cgroup`.
'';
};
extraConfigPaths = mkOption {
type = with types; listOf path;
extraConfigPaths = lib.mkOption {
type = with lib.types; listOf path;
default = [];
description = ''
Slurm expects config files for plugins in the same path
@ -273,11 +270,11 @@ in
'';
};
etcSlurm = mkOption {
type = types.path;
etcSlurm = lib.mkOption {
type = lib.types.path;
internal = true;
default = etcSlurm;
defaultText = literalMD ''
defaultText = lib.literalMD ''
Directory created from generated config files and
`config.${opt.extraConfigPaths}`.
'';
@ -292,11 +289,11 @@ in
};
imports = [
(mkRemovedOptionModule [ "services" "slurm" "dbdserver" "storagePass" ] ''
(lib.mkRemovedOptionModule [ "services" "slurm" "dbdserver" "storagePass" ] ''
This option has been removed so that the database password is not exposed via the nix store.
Use services.slurm.dbdserver.storagePassFile to provide the database password.
'')
(mkRemovedOptionModule [ "services" "slurm" "dbdserver" "configFile" ] ''
(lib.mkRemovedOptionModule [ "services" "slurm" "dbdserver" "configFile" ] ''
This option has been removed. Use services.slurm.dbdserver.storagePassFile
and services.slurm.dbdserver.extraConfig instead.
'')
@ -312,7 +309,7 @@ in
builder = pkgs.writeText "builder.sh" ''
source $stdenv/setup
mkdir -p $out/bin
find ${getBin cfg.package}/bin -type f -executable | while read EXE
find ${lib.getBin cfg.package}/bin -type f -executable | while read EXE
do
exename="$(basename $EXE)"
wrappername="$out/bin/$exename"
@ -329,21 +326,21 @@ in
done
mkdir -p $out/share
ln -s ${getBin cfg.package}/share/man $out/share/man
ln -s ${lib.getBin cfg.package}/share/man $out/share/man
'';
};
in mkIf ( cfg.enableStools ||
in lib.mkIf ( cfg.enableStools ||
cfg.client.enable ||
cfg.server.enable ||
cfg.dbdserver.enable ) {
environment.systemPackages = [ wrappedSlurm ];
services.munge.enable = mkDefault true;
services.munge.enable = lib.mkDefault true;
# use a static uid as default to ensure it is the same on all nodes
users.users.slurm = mkIf (cfg.user == defaultUser) {
users.users.slurm = lib.mkIf (cfg.user == defaultUser) {
name = defaultUser;
group = "slurm";
uid = config.ids.uids.slurm;
@ -351,7 +348,7 @@ in
users.groups.slurm.gid = config.ids.uids.slurm;
systemd.services.slurmd = mkIf (cfg.client.enable) {
systemd.services.slurmd = lib.mkIf (cfg.client.enable) {
path = with pkgs; [ wrappedSlurm coreutils ]
++ lib.optional cfg.enableSrunX11 slurm-spank-x11;
@ -375,13 +372,13 @@ in
};
};
systemd.tmpfiles.rules = mkIf cfg.client.enable [
systemd.tmpfiles.rules = lib.mkIf cfg.client.enable [
"d /var/spool/slurmd 755 root root -"
];
services.openssh.settings.X11Forwarding = mkIf cfg.client.enable (mkDefault true);
services.openssh.settings.X11Forwarding = lib.mkIf cfg.client.enable (lib.mkDefault true);
systemd.services.slurmctld = mkIf (cfg.server.enable) {
systemd.services.slurmctld = lib.mkIf (cfg.server.enable) {
path = with pkgs; [ wrappedSlurm munge coreutils ]
++ lib.optional cfg.enableSrunX11 slurm-spank-x11;
@ -405,7 +402,7 @@ in
systemd.services.slurmdbd = let
# slurm strips the last component off the path
configPath = "$RUNTIME_DIRECTORY/slurmdbd.conf";
in mkIf (cfg.dbdserver.enable) {
in lib.mkIf (cfg.dbdserver.enable) {
path = with pkgs; [ wrappedSlurm munge coreutils ];
wantedBy = [ "multi-user.target" ];
@ -414,7 +411,7 @@ in
preStart = ''
install -m 600 -o ${cfg.user} -T ${slurmdbdConf} ${configPath}
${optionalString (cfg.dbdserver.storagePassFile != null) ''
${lib.optionalString (cfg.dbdserver.storagePassFile != null) ''
echo "StoragePass=$(cat ${cfg.dbdserver.storagePassFile})" \
>> ${configPath}
''}

View File

@ -1,7 +1,4 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.torque.mom;
@ -17,10 +14,10 @@ in
options = {
services.torque.mom = {
enable = mkEnableOption "torque computing node";
enable = lib.mkEnableOption "torque computing node";
serverNode = mkOption {
type = types.str;
serverNode = lib.mkOption {
type = lib.types.str;
description = "Hostname running pbs server.";
};
@ -28,7 +25,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.torque ];
systemd.services.torque-mom-init = {

View File

@ -1,7 +1,4 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.torque.server;
torque = pkgs.torque;
@ -11,13 +8,13 @@ in
services.torque.server = {
enable = mkEnableOption "torque server";
enable = lib.mkEnableOption "torque server";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.torque ];
systemd.services.torque-server-init = {

View File

@ -1,9 +1,5 @@
# NixOS module for Buildbot continuous integration server.
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.buildbot-master;
opt = options.services.buildbot-master;
@ -11,27 +7,27 @@ let
package = pkgs.python3.pkgs.toPythonModule cfg.package;
python = package.pythonModule;
escapeStr = escape [ "'" ];
escapeStr = lib.escape [ "'" ];
defaultMasterCfg = pkgs.writeText "master.cfg" ''
from buildbot.plugins import *
${cfg.extraImports}
factory = util.BuildFactory()
c = BuildmasterConfig = dict(
workers = [${concatStringsSep "," cfg.workers}],
workers = [${lib.concatStringsSep "," cfg.workers}],
protocols = { 'pb': {'port': ${toString cfg.pbPort} } },
title = '${escapeStr cfg.title}',
titleURL = '${escapeStr cfg.titleUrl}',
buildbotURL = '${escapeStr cfg.buildbotUrl}',
db = dict(db_url='${escapeStr cfg.dbUrl}'),
title = '${lib.escapeStr cfg.title}',
titleURL = '${lib.escapeStr cfg.titleUrl}',
buildbotURL = '${lib.escapeStr cfg.buildbotUrl}',
db = dict(db_url='${lib.escapeStr cfg.dbUrl}'),
www = dict(port=${toString cfg.port}),
change_source = [ ${concatStringsSep "," cfg.changeSource} ],
schedulers = [ ${concatStringsSep "," cfg.schedulers} ],
builders = [ ${concatStringsSep "," cfg.builders} ],
services = [ ${concatStringsSep "," cfg.reporters} ],
configurators = [ ${concatStringsSep "," cfg.configurators} ],
change_source = [ ${lib.concatStringsSep "," cfg.changeSource} ],
schedulers = [ ${lib.concatStringsSep "," cfg.schedulers} ],
builders = [ ${lib.concatStringsSep "," cfg.builders} ],
services = [ ${lib.concatStringsSep "," cfg.reporters} ],
configurators = [ ${lib.concatStringsSep "," cfg.configurators} ],
)
for step in [ ${concatStringsSep "," cfg.factorySteps} ]:
for step in [ ${lib.concatStringsSep "," cfg.factorySteps} ]:
factory.addStep(step)
${cfg.extraConfig}
@ -62,8 +58,8 @@ in {
options = {
services.buildbot-master = {
factorySteps = mkOption {
type = types.listOf types.str;
factorySteps = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Factory Steps";
default = [];
example = [
@ -72,8 +68,8 @@ in {
];
};
changeSource = mkOption {
type = types.listOf types.str;
changeSource = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "List of Change Sources.";
default = [];
example = [
@ -81,8 +77,8 @@ in {
];
};
configurators = mkOption {
type = types.listOf types.str;
configurators = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Configurator Steps, see https://docs.buildbot.net/latest/manual/configuration/configurators.html";
default = [];
example = [
@ -90,35 +86,35 @@ in {
];
};
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable the Buildbot continuous integration server.";
};
extraConfig = mkOption {
type = types.str;
extraConfig = lib.mkOption {
type = lib.types.str;
description = "Extra configuration to append to master.cfg";
default = "c['buildbotNetUsageData'] = None";
};
extraImports = mkOption {
type = types.str;
extraImports = lib.mkOption {
type = lib.types.str;
description = "Extra python imports to prepend to master.cfg";
default = "";
example = "from buildbot.process.project import Project";
};
masterCfg = mkOption {
type = types.path;
masterCfg = lib.mkOption {
type = lib.types.path;
description = "Optionally pass master.cfg path. Other options in this configuration will be ignored.";
default = defaultMasterCfg;
defaultText = literalMD ''generated configuration file'';
defaultText = lib.literalMD ''generated configuration file'';
example = "/etc/nixos/buildbot/master.cfg";
};
schedulers = mkOption {
type = types.listOf types.str;
schedulers = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "List of Schedulers.";
default = [
"schedulers.SingleBranchScheduler(name='all', change_filter=util.ChangeFilter(branch='master'), treeStableTimer=None, builderNames=['runtests'])"
@ -126,60 +122,60 @@ in {
];
};
builders = mkOption {
type = types.listOf types.str;
builders = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "List of Builders.";
default = [
"util.BuilderConfig(name='runtests',workernames=['example-worker'],factory=factory)"
];
};
workers = mkOption {
type = types.listOf types.str;
workers = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "List of Workers.";
default = [ "worker.Worker('example-worker', 'pass')" ];
};
reporters = mkOption {
reporters = lib.mkOption {
default = [];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = "List of reporter objects used to present build status to various users.";
};
user = mkOption {
user = lib.mkOption {
default = "buildbot";
type = types.str;
type = lib.types.str;
description = "User the buildbot server should execute under.";
};
group = mkOption {
group = lib.mkOption {
default = "buildbot";
type = types.str;
type = lib.types.str;
description = "Primary group of buildbot user.";
};
extraGroups = mkOption {
type = types.listOf types.str;
extraGroups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = "List of extra groups that the buildbot user should be a part of.";
};
home = mkOption {
home = lib.mkOption {
default = "/home/buildbot";
type = types.path;
type = lib.types.path;
description = "Buildbot home directory.";
};
buildbotDir = mkOption {
buildbotDir = lib.mkOption {
default = "${cfg.home}/master";
defaultText = literalExpression ''"''${config.${opt.home}}/master"'';
type = types.path;
defaultText = lib.literalExpression ''"''${config.${opt.home}}/master"'';
type = lib.types.path;
description = "Specifies the Buildbot directory.";
};
pbPort = mkOption {
pbPort = lib.mkOption {
default = 9989;
type = types.either types.str types.int;
type = lib.types.either lib.types.str lib.types.int;
example = "'tcp:9990:interface=127.0.0.1'";
description = ''
The buildmaster will listen on a TCP port of your choosing
@ -193,69 +189,69 @@ in {
'';
};
listenAddress = mkOption {
listenAddress = lib.mkOption {
default = "0.0.0.0";
type = types.str;
type = lib.types.str;
description = "Specifies the bind address on which the buildbot HTTP interface listens.";
};
buildbotUrl = mkOption {
buildbotUrl = lib.mkOption {
default = "http://localhost:8010/";
type = types.str;
type = lib.types.str;
description = "Specifies the Buildbot URL.";
};
title = mkOption {
title = lib.mkOption {
default = "Buildbot";
type = types.str;
type = lib.types.str;
description = "Specifies the Buildbot Title.";
};
titleUrl = mkOption {
titleUrl = lib.mkOption {
default = "Buildbot";
type = types.str;
type = lib.types.str;
description = "Specifies the Buildbot TitleURL.";
};
dbUrl = mkOption {
dbUrl = lib.mkOption {
default = "sqlite:///state.sqlite";
type = types.str;
type = lib.types.str;
description = "Specifies the database connection string.";
};
port = mkOption {
port = lib.mkOption {
default = 8010;
type = types.port;
type = lib.types.port;
description = "Specifies port number on which the buildbot HTTP interface listens.";
};
package = mkPackageOption pkgs "buildbot-full" {
package = lib.mkPackageOption pkgs "buildbot-full" {
example = "buildbot";
};
packages = mkOption {
packages = lib.mkOption {
default = [ pkgs.git ];
defaultText = literalExpression "[ pkgs.git ]";
type = types.listOf types.package;
defaultText = lib.literalExpression "[ pkgs.git ]";
type = lib.types.listOf lib.types.package;
description = "Packages to add to PATH for the buildbot process.";
};
pythonPackages = mkOption {
type = types.functionTo (types.listOf types.package);
pythonPackages = lib.mkOption {
type = lib.types.functionTo (lib.types.listOf lib.types.package);
default = pythonPackages: with pythonPackages; [ ];
defaultText = literalExpression "pythonPackages: with pythonPackages; [ ]";
defaultText = lib.literalExpression "pythonPackages: with pythonPackages; [ ]";
description = "Packages to add the to the PYTHONPATH of the buildbot process.";
example = literalExpression "pythonPackages: with pythonPackages; [ requests ]";
example = lib.literalExpression "pythonPackages: with pythonPackages; [ requests ]";
};
};
};
config = mkIf cfg.enable {
users.groups = optionalAttrs (cfg.group == "buildbot") {
config = lib.mkIf cfg.enable {
users.groups = lib.optionalAttrs (cfg.group == "buildbot") {
buildbot = { };
};
users.users = optionalAttrs (cfg.user == "buildbot") {
users.users = lib.optionalAttrs (cfg.user == "buildbot") {
buildbot = {
description = "Buildbot User.";
isNormalUser = true;
@ -298,8 +294,8 @@ in {
};
imports = [
(mkRenamedOptionModule [ "services" "buildbot-master" "bpPort" ] [ "services" "buildbot-master" "pbPort" ])
(mkRemovedOptionModule [ "services" "buildbot-master" "status" ] ''
(lib.mkRenamedOptionModule [ "services" "buildbot-master" "bpPort" ] [ "services" "buildbot-master" "pbPort" ])
(lib.mkRemovedOptionModule [ "services" "buildbot-master" "status" ] ''
Since Buildbot 0.9.0, status targets are deprecated and ignored.
Review your configuration and migrate to reporters (available at services.buildbot-master.reporters).
'')

View File

@ -1,7 +1,4 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.etcd;
opt = options.services.etcd;
@ -9,98 +6,98 @@ let
in {
options.services.etcd = {
enable = mkOption {
enable = lib.mkOption {
description = "Whether to enable etcd.";
default = false;
type = types.bool;
type = lib.types.bool;
};
package = mkPackageOption pkgs "etcd" { };
package = lib.mkPackageOption pkgs "etcd" { };
name = mkOption {
name = lib.mkOption {
description = "Etcd unique node name.";
default = config.networking.hostName;
defaultText = literalExpression "config.networking.hostName";
type = types.str;
defaultText = lib.literalExpression "config.networking.hostName";
type = lib.types.str;
};
advertiseClientUrls = mkOption {
advertiseClientUrls = lib.mkOption {
description = "Etcd list of this member's client URLs to advertise to the rest of the cluster.";
default = cfg.listenClientUrls;
defaultText = literalExpression "config.${opt.listenClientUrls}";
type = types.listOf types.str;
defaultText = lib.literalExpression "config.${opt.listenClientUrls}";
type = lib.types.listOf lib.types.str;
};
listenClientUrls = mkOption {
listenClientUrls = lib.mkOption {
description = "Etcd list of URLs to listen on for client traffic.";
default = ["http://127.0.0.1:2379"];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
};
listenPeerUrls = mkOption {
listenPeerUrls = lib.mkOption {
description = "Etcd list of URLs to listen on for peer traffic.";
default = ["http://127.0.0.1:2380"];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
};
initialAdvertisePeerUrls = mkOption {
initialAdvertisePeerUrls = lib.mkOption {
description = "Etcd list of this member's peer URLs to advertise to rest of the cluster.";
default = cfg.listenPeerUrls;
defaultText = literalExpression "config.${opt.listenPeerUrls}";
type = types.listOf types.str;
defaultText = lib.literalExpression "config.${opt.listenPeerUrls}";
type = lib.types.listOf lib.types.str;
};
initialCluster = mkOption {
initialCluster = lib.mkOption {
description = "Etcd initial cluster configuration for bootstrapping.";
default = ["${cfg.name}=http://127.0.0.1:2380"];
defaultText = literalExpression ''["''${config.${opt.name}}=http://127.0.0.1:2380"]'';
type = types.listOf types.str;
defaultText = lib.literalExpression ''["''${config.${opt.name}}=http://127.0.0.1:2380"]'';
type = lib.types.listOf lib.types.str;
};
initialClusterState = mkOption {
initialClusterState = lib.mkOption {
description = "Etcd initial cluster configuration for bootstrapping.";
default = "new";
type = types.enum ["new" "existing"];
type = lib.types.enum ["new" "existing"];
};
initialClusterToken = mkOption {
initialClusterToken = lib.mkOption {
description = "Etcd initial cluster token for etcd cluster during bootstrap.";
default = "etcd-cluster";
type = types.str;
type = lib.types.str;
};
discovery = mkOption {
discovery = lib.mkOption {
description = "Etcd discovery url";
default = "";
type = types.str;
type = lib.types.str;
};
clientCertAuth = mkOption {
clientCertAuth = lib.mkOption {
description = "Whether to use certs for client authentication";
default = false;
type = types.bool;
type = lib.types.bool;
};
trustedCaFile = mkOption {
trustedCaFile = lib.mkOption {
description = "Certificate authority file to use for clients";
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
};
certFile = mkOption {
certFile = lib.mkOption {
description = "Cert file to use for clients";
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
};
keyFile = mkOption {
keyFile = lib.mkOption {
description = "Key file to use for clients";
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Open etcd ports in the firewall.
@ -110,41 +107,41 @@ in {
'';
};
peerCertFile = mkOption {
peerCertFile = lib.mkOption {
description = "Cert file to use for peer to peer communication";
default = cfg.certFile;
defaultText = literalExpression "config.${opt.certFile}";
type = types.nullOr types.path;
defaultText = lib.literalExpression "config.${opt.certFile}";
type = lib.types.nullOr lib.types.path;
};
peerKeyFile = mkOption {
peerKeyFile = lib.mkOption {
description = "Key file to use for peer to peer communication";
default = cfg.keyFile;
defaultText = literalExpression "config.${opt.keyFile}";
type = types.nullOr types.path;
defaultText = lib.literalExpression "config.${opt.keyFile}";
type = lib.types.nullOr lib.types.path;
};
peerTrustedCaFile = mkOption {
peerTrustedCaFile = lib.mkOption {
description = "Certificate authority file to use for peer to peer communication";
default = cfg.trustedCaFile;
defaultText = literalExpression "config.${opt.trustedCaFile}";
type = types.nullOr types.path;
defaultText = lib.literalExpression "config.${opt.trustedCaFile}";
type = lib.types.nullOr lib.types.path;
};
peerClientCertAuth = mkOption {
peerClientCertAuth = lib.mkOption {
description = "Whether to check all incoming peer requests from the cluster for valid client certificates signed by the supplied CA";
default = false;
type = types.bool;
type = lib.types.bool;
};
extraConf = mkOption {
extraConf = lib.mkOption {
description = ''
Etcd extra configuration. See
<https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md#configuration-flags>
'';
type = types.attrsOf types.str;
type = lib.types.attrsOf lib.types.str;
default = {};
example = literalExpression ''
example = lib.literalExpression ''
{
"CORS" = "*";
"NAME" = "default-name";
@ -155,14 +152,14 @@ in {
'';
};
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/etcd";
description = "Etcd data directory.";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.tmpfiles.settings."10-etcd".${cfg.dataDir}.d = {
user = "etcd";
mode = "0700";
@ -176,14 +173,14 @@ in {
wants = [ "network-online.target" ]
++ lib.optional config.networking.firewall.enable "firewall.service";
environment = (filterAttrs (n: v: v != null) {
environment = (lib.filterAttrs (n: v: v != null) {
ETCD_NAME = cfg.name;
ETCD_DISCOVERY = cfg.discovery;
ETCD_DATA_DIR = cfg.dataDir;
ETCD_ADVERTISE_CLIENT_URLS = concatStringsSep "," cfg.advertiseClientUrls;
ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls;
ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls;
ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls;
ETCD_ADVERTISE_CLIENT_URLS = lib.concatStringsSep "," cfg.advertiseClientUrls;
ETCD_LISTEN_CLIENT_URLS = lib.concatStringsSep "," cfg.listenClientUrls;
ETCD_LISTEN_PEER_URLS = lib.concatStringsSep "," cfg.listenPeerUrls;
ETCD_INITIAL_ADVERTISE_PEER_URLS = lib.concatStringsSep "," cfg.initialAdvertisePeerUrls;
ETCD_PEER_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth;
ETCD_PEER_TRUSTED_CA_FILE = cfg.peerTrustedCaFile;
ETCD_PEER_CERT_FILE = cfg.peerCertFile;
@ -192,11 +189,11 @@ in {
ETCD_TRUSTED_CA_FILE = cfg.trustedCaFile;
ETCD_CERT_FILE = cfg.certFile;
ETCD_KEY_FILE = cfg.keyFile;
}) // (optionalAttrs (cfg.discovery == ""){
ETCD_INITIAL_CLUSTER = concatStringsSep "," cfg.initialCluster;
}) // (lib.optionalAttrs (cfg.discovery == ""){
ETCD_INITIAL_CLUSTER = lib.concatStringsSep "," cfg.initialCluster;
ETCD_INITIAL_CLUSTER_STATE = cfg.initialClusterState;
ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken;
}) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf);
}) // (lib.mapAttrs' (n: v: lib.nameValuePair "ETCD_${n}" v) cfg.extraConf);
unitConfig = {
Documentation = "https://github.com/coreos/etcd";

View File

@ -52,11 +52,9 @@ let
server.directories.run=${cfg.directories.home}/run
# HTTP Connector
${lib.optionalString (cfg.http.enable) ''
server.http.enabled=${lib.boolToString cfg.http.enable}
server.http.listen_address=${cfg.http.listenAddress}
server.http.advertised_address=${cfg.http.listenAddress}
''}
server.http.enabled=${lib.boolToString cfg.http.enable}
server.http.listen_address=${cfg.http.listenAddress}
server.http.advertised_address=${cfg.http.listenAddress}
# HTTPS Connector
server.https.enabled=${lib.boolToString cfg.https.enable}

View File

@ -1,23 +1,17 @@
# AccountsService daemon.
{ config, lib, pkgs, ... }:
with lib;
{
meta = {
maintainers = teams.freedesktop.members;
maintainers = lib.teams.freedesktop.members;
};
###### interface
options = {
services.accounts-daemon = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable AccountsService, a DBus service for accessing
@ -29,10 +23,8 @@ with lib;
};
###### implementation
config = mkIf config.services.accounts-daemon.enable {
config = lib.mkIf config.services.accounts-daemon.enable {
environment.systemPackages = [ pkgs.accountsservice ];
@ -43,14 +35,14 @@ with lib;
systemd.packages = [ pkgs.accountsservice ];
systemd.services.accounts-daemon = recursiveUpdate {
systemd.services.accounts-daemon = lib.recursiveUpdate {
wantedBy = [ "graphical.target" ];
# Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice
environment.XDG_DATA_DIRS = "${config.system.path}/share";
} (optionalAttrs (!config.users.mutableUsers) {
} (lib.optionalAttrs (!config.users.mutableUsers) {
environment.NIXOS_USERS_PURE = "true";
});
};

View File

@ -1,25 +1,21 @@
# Bamf
{ config, lib, pkgs, ... }:
with lib;
{
meta = with lib; {
maintainers = with maintainers; [ ] ++ teams.pantheon.members;
maintainers = with lib.maintainers; [ ] ++ lib.teams.pantheon.members;
};
###### interface
options = {
services.bamf = {
enable = mkEnableOption "bamf";
enable = lib.mkEnableOption "bamf";
};
};
###### implementation
config = mkIf config.services.bamf.enable {
config = lib.mkIf config.services.bamf.enable {
services.dbus.packages = [ pkgs.bamf ];
systemd.packages = [ pkgs.bamf ];

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rspamd-trainer;
@ -10,18 +7,18 @@ let
in {
options.services.rspamd-trainer = {
enable = mkEnableOption "Spam/ham trainer for rspamd";
enable = lib.mkEnableOption "Spam/ham trainer for rspamd";
settings = mkOption {
settings = lib.mkOption {
default = { };
description = ''
IMAP authentication configuration for rspamd-trainer. For supplying
the IMAP password, use the `secrets` option.
'';
type = types.submodule {
type = lib.types.submodule {
freeformType = format.type;
};
example = literalExpression ''
example = lib.literalExpression ''
{
HOST = "localhost";
USERNAME = "spam@example.com";
@ -31,7 +28,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. For the
@ -42,7 +39,7 @@ in {
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd = {
services.rspamd-trainer = {

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rss2email;
in {
@ -12,25 +9,25 @@ in {
services.rss2email = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable rss2email.";
};
to = mkOption {
type = types.str;
to = lib.mkOption {
type = lib.types.str;
description = "Mail address to which to send emails";
};
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "12h";
description = "How often to check the feeds, in systemd interval format";
};
config = mkOption {
type = with types; attrsOf (oneOf [ str int bool ]);
config = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ str int bool ]);
default = {};
description = ''
The configuration to give rss2email.
@ -48,17 +45,17 @@ in {
'';
};
feeds = mkOption {
feeds = lib.mkOption {
description = "The feeds to watch.";
type = types.attrsOf (types.submodule {
type = lib.types.attrsOf (lib.types.submodule {
options = {
url = mkOption {
type = types.str;
url = lib.mkOption {
type = lib.types.str;
description = "The URL at which to fetch the feed.";
};
to = mkOption {
type = with types; nullOr str;
to = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Email address to which to send feed items.
@ -78,7 +75,7 @@ in {
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.groups = {
rss2email.gid = config.ids.gids.rss2email;
};
@ -104,7 +101,7 @@ in {
systemd.services.rss2email = let
conf = pkgs.writeText "rss2email.cfg" (lib.generators.toINI {} ({
DEFAULT = cfg.config;
} // lib.mapAttrs' (name: feed: nameValuePair "feed.${name}" (
} // lib.mapAttrs' (name: feed: lib.nameValuePair "feed.${name}" (
{ inherit (feed) url; } //
lib.optionalAttrs (feed.to != null) { inherit (feed) to; }
)) cfg.feeds

View File

@ -258,7 +258,7 @@ in
default = { };
description = ''
Configuration for dendrite, see:
<https://github.com/matrix-org/dendrite/blob/master/dendrite-config.yaml>
<https://github.com/matrix-org/dendrite/blob/main/dendrite-sample.yaml>
for available options with which to populate settings.
'';
};

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gitolite;
# Use writeTextDir to not leak Nix store hash into file name
@ -11,8 +8,8 @@ in
{
options = {
services.gitolite = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Enable gitolite management under the
@ -22,8 +19,8 @@ in
'';
};
dataDir = mkOption {
type = types.str;
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gitolite";
description = ''
The gitolite home directory used to store all repositories. If left as the default value
@ -33,8 +30,8 @@ in
'';
};
adminPubkey = mkOption {
type = types.str;
adminPubkey = lib.mkOption {
type = lib.types.str;
description = ''
Initial administrative public key for Gitolite. This should
be an SSH Public Key. Note that this key will only be used
@ -43,8 +40,8 @@ in
'';
};
enableGitAnnex = mkOption {
type = types.bool;
enableGitAnnex = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Enable git-annex support. Uses the `extraGitoliteRc` option
@ -52,18 +49,18 @@ in
'';
};
commonHooks = mkOption {
type = types.listOf types.path;
commonHooks = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [];
description = ''
A list of custom git hooks that get copied to `~/.gitolite/hooks/common`.
'';
};
extraGitoliteRc = mkOption {
type = types.lines;
extraGitoliteRc = lib.mkOption {
type = lib.types.lines;
default = "";
example = literalExpression ''
example = lib.literalExpression ''
'''
$RC{UMASK} = 0027;
$RC{SITE_INFO} = 'This is our private repository host';
@ -93,24 +90,24 @@ in
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "gitolite";
description = ''
Gitolite user account. This is the username of the gitolite endpoint.
'';
};
description = mkOption {
type = types.str;
description = lib.mkOption {
type = lib.types.str;
default = "Gitolite user";
description = ''
Gitolite user account's description.
'';
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "gitolite";
description = ''
Primary group of the Gitolite user account.
@ -119,7 +116,7 @@ in
};
};
config = mkIf cfg.enable (
config = lib.mkIf cfg.enable (
let
manageGitoliteRc = cfg.extraGitoliteRc != "";
rcDir = pkgs.runCommand "gitolite-rc" { preferLocalBuild = true; } rcDirScript;
@ -136,18 +133,18 @@ in
END
cat "$out/gitolite.rc.default" >>"$out/gitolite.rc"
'' +
optionalString (cfg.extraGitoliteRc != "") ''
echo -n ${escapeShellArg ''
lib.optionalString (cfg.extraGitoliteRc != "") ''
echo -n ${lib.escapeShellArg ''
# Added by NixOS:
${removeSuffix "\n" cfg.extraGitoliteRc}
${lib.removeSuffix "\n" cfg.extraGitoliteRc}
# per perl rules, this should be the last line in such a file:
1;
''} >>"$out/gitolite.rc"
'';
in {
services.gitolite.extraGitoliteRc = optionalString cfg.enableGitAnnex ''
services.gitolite.extraGitoliteRc = lib.optionalString cfg.enableGitAnnex ''
# Enable git-annex support:
push( @{$RC{ENABLE}}, 'git-annex-shell ua');
'';
@ -171,8 +168,8 @@ in
GITOLITE_RC_DEFAULT = "${rcDir}/gitolite.rc.default";
};
serviceConfig = mkMerge [
(mkIf (cfg.dataDir == "/var/lib/gitolite") {
serviceConfig = lib.mkMerge [
(lib.mkIf (cfg.dataDir == "/var/lib/gitolite") {
StateDirectory = "gitolite gitolite/.gitolite gitolite/.gitolite/logs";
StateDirectoryMode = "0750";
})
@ -236,6 +233,6 @@ in
};
environment.systemPackages = [ pkgs.gitolite pkgs.git ]
++ optional cfg.enableGitAnnex pkgs.git-annex;
++ lib.optional cfg.enableGitAnnex pkgs.git-annex;
});
}

View File

@ -1,7 +1,4 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.gogs;
opt = options.services.gogs;
@ -29,7 +26,7 @@ let
[session]
COOKIE_NAME = session
COOKIE_SECURE = ${boolToString cfg.cookieSecure}
COOKIE_SECURE = ${lib.boolToString cfg.cookieSecure}
[security]
SECRET_KEY = #secretkey#
@ -45,70 +42,70 @@ in
{
options = {
services.gogs = {
enable = mkOption {
enable = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = "Enable Go Git Service.";
};
useWizard = mkOption {
useWizard = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator.";
};
stateDir = mkOption {
stateDir = lib.mkOption {
default = "/var/lib/gogs";
type = types.str;
type = lib.types.str;
description = "Gogs data directory.";
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "gogs";
description = "User account under which Gogs runs.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "gogs";
description = "Group account under which Gogs runs.";
};
database = {
type = mkOption {
type = types.enum [ "sqlite3" "mysql" "postgres" ];
type = lib.mkOption {
type = lib.types.enum [ "sqlite3" "mysql" "postgres" ];
example = "mysql";
default = "sqlite3";
description = "Database engine to use.";
};
host = mkOption {
type = types.str;
host = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Database host address.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 3306;
description = "Database host port.";
};
name = mkOption {
type = types.str;
name = lib.mkOption {
type = lib.types.str;
default = "gogs";
description = "Database name.";
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "gogs";
description = "Database user.";
};
password = mkOption {
type = types.str;
password = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
The password corresponding to {option}`database.user`.
@ -117,8 +114,8 @@ in
'';
};
passwordFile = mkOption {
type = types.nullOr types.path;
passwordFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = "/run/keys/gogs-dbpassword";
description = ''
@ -127,53 +124,53 @@ in
'';
};
path = mkOption {
type = types.str;
path = lib.mkOption {
type = lib.types.str;
default = "${cfg.stateDir}/data/gogs.db";
defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/gogs.db"'';
defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/data/gogs.db"'';
description = "Path to the sqlite3 database file.";
};
};
appName = mkOption {
type = types.str;
appName = lib.mkOption {
type = lib.types.str;
default = "Gogs: Go Git Service";
description = "Application name.";
};
repositoryRoot = mkOption {
type = types.str;
repositoryRoot = lib.mkOption {
type = lib.types.str;
default = "${cfg.stateDir}/repositories";
defaultText = literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
description = "Path to the git repositories.";
};
domain = mkOption {
type = types.str;
domain = lib.mkOption {
type = lib.types.str;
default = "localhost";
description = "Domain name of your server.";
};
rootUrl = mkOption {
type = types.str;
rootUrl = lib.mkOption {
type = lib.types.str;
default = "http://localhost:3000/";
description = "Full public URL of Gogs server.";
};
httpAddress = mkOption {
type = types.str;
httpAddress = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
description = "HTTP listen address.";
};
httpPort = mkOption {
type = types.port;
httpPort = lib.mkOption {
type = lib.types.port;
default = 3000;
description = "HTTP listen port.";
};
cookieSecure = mkOption {
type = types.bool;
cookieSecure = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Marks session cookies as "secure" as a hint for browsers to only send
@ -181,15 +178,15 @@ in
'';
};
extraConfig = mkOption {
type = types.str;
extraConfig = lib.mkOption {
type = lib.types.str;
default = "";
description = "Configuration lines appended to the generated Gogs configuration file.";
};
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.gogs = {
description = "Gogs (Go Git Service)";
@ -204,7 +201,7 @@ in
mkdir -p ${cfg.stateDir}
# copy custom configuration and generate a random secret key if needed
${optionalString (cfg.useWizard == false) ''
${lib.optionalString (cfg.useWizard == false) ''
mkdir -p ${cfg.stateDir}/custom/conf
cp -f ${configFile} ${runConfig}
@ -248,7 +245,7 @@ in
};
};
users = mkIf (cfg.user == "gogs") {
users = lib.mkIf (cfg.user == "gogs") {
users.gogs = {
description = "Go Git Service";
uid = config.ids.uids.gogs;
@ -260,13 +257,13 @@ in
groups.gogs.gid = config.ids.gids.gogs;
};
warnings = optional (cfg.database.password != "")
warnings = lib.optional (cfg.database.password != "")
''config.services.gogs.database.password will be stored as plaintext
in the Nix store. Use database.passwordFile instead.'';
# Create database passwordFile default when password is configured.
services.gogs.database.passwordFile =
(mkDefault (toString (pkgs.writeTextFile {
(lib.mkDefault (toString (pkgs.writeTextFile {
name = "gogs-database-password";
text = cfg.database.password;
})));

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (config.security) wrapperDir;
cfg = config.services.kbfs;
@ -12,14 +11,14 @@ in {
services.kbfs = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to mount the Keybase filesystem.";
};
enableRedirector = mkOption {
type = types.bool;
enableRedirector = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the Keybase root redirector service, allowing
@ -28,15 +27,15 @@ in {
'';
};
mountPoint = mkOption {
type = types.str;
mountPoint = lib.mkOption {
type = lib.types.str;
default = "%h/keybase";
example = "/keybase";
description = "Mountpoint for the Keybase filesystem.";
};
extraFlags = mkOption {
type = types.listOf types.str;
extraFlags = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = [
"-label kbfs"
@ -52,7 +51,7 @@ in {
###### implementation
config = mkIf cfg.enable (mkMerge [
config = lib.mkIf cfg.enable (lib.mkMerge [
{
# Upstream: https://github.com/keybase/client/blob/master/packaging/linux/systemd/kbfs.service
systemd.user.services.kbfs = {
@ -61,7 +60,7 @@ in {
# Note that the "Requires" directive will cause a unit to be restarted whenever its dependency is restarted.
# Do not issue a hard dependency on keybase, because kbfs can reconnect to a restarted service.
# Do not issue a hard dependency on keybase-redirector, because it's ok if it fails (e.g., if it is disabled).
wants = [ "keybase.service" ] ++ optional cfg.enableRedirector "keybase-redirector.service";
wants = [ "keybase.service" ] ++ lib.optional cfg.enableRedirector "keybase-redirector.service";
path = [ "/run/wrappers" ];
unitConfig.ConditionUser = "!@system";
@ -89,7 +88,7 @@ in {
environment.systemPackages = [ pkgs.kbfs ];
}
(mkIf cfg.enableRedirector {
(lib.mkIf cfg.enableRedirector {
security.wrappers."keybase-redirector".source = "${pkgs.kbfs}/bin/redirector";
systemd.tmpfiles.settings."10-kbfs"."/keybase".d = {

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
cfg = config.services.kubo;
@ -35,11 +34,11 @@ let
'';
kuboFlags = utils.escapeSystemdExecArgs (
optional cfg.autoMount "--mount" ++
optional cfg.enableGC "--enable-gc" ++
optional (cfg.serviceFdlimit != null) "--manage-fdlimit=false" ++
optional (cfg.defaultMode == "offline") "--offline" ++
optional (cfg.defaultMode == "norouting") "--routing=none" ++
lib.optional cfg.autoMount "--mount" ++
lib.optional cfg.enableGC "--enable-gc" ++
lib.optional (cfg.serviceFdlimit != null) "--manage-fdlimit=false" ++
lib.optional (cfg.defaultMode == "offline") "--offline" ++
lib.optional (cfg.defaultMode == "norouting") "--routing=none" ++
cfg.extraFlags
);
@ -99,78 +98,78 @@ in
services.kubo = {
enable = mkEnableOption ''
enable = lib.mkEnableOption ''
the Interplanetary File System (WARNING: may cause severe network degradation).
NOTE: after enabling this option and rebuilding your system, you need to log out
and back in for the `IPFS_PATH` environment variable to be present in your shell.
Until you do that, the CLI tools won't be able to talk to the daemon by default
'';
package = mkPackageOption pkgs "kubo" { };
package = lib.mkPackageOption pkgs "kubo" { };
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "ipfs";
description = "User under which the Kubo daemon runs";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "ipfs";
description = "Group under which the Kubo daemon runs";
};
dataDir = mkOption {
type = types.str;
dataDir = lib.mkOption {
type = lib.types.str;
default =
if versionAtLeast config.system.stateVersion "17.09"
if lib.versionAtLeast config.system.stateVersion "17.09"
then "/var/lib/ipfs"
else "/var/lib/ipfs/.ipfs";
defaultText = literalExpression ''
if versionAtLeast config.system.stateVersion "17.09"
defaultText = lib.literalExpression ''
if lib.versionAtLeast config.system.stateVersion "17.09"
then "/var/lib/ipfs"
else "/var/lib/ipfs/.ipfs"
'';
description = "The data dir for Kubo";
};
defaultMode = mkOption {
type = types.enum [ "online" "offline" "norouting" ];
defaultMode = lib.mkOption {
type = lib.types.enum [ "online" "offline" "norouting" ];
default = "online";
description = "systemd service that is enabled by default";
};
autoMount = mkOption {
type = types.bool;
autoMount = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether Kubo should try to mount /ipfs and /ipns at startup.";
};
autoMigrate = mkOption {
type = types.bool;
autoMigrate = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether Kubo should try to run the fs-repo-migration at startup.";
};
enableGC = mkOption {
type = types.bool;
enableGC = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable automatic garbage collection";
};
emptyRepo = mkOption {
type = types.bool;
emptyRepo = lib.mkOption {
type = lib.types.bool;
default = true;
description = "If set to false, the repo will be initialized with help files";
};
settings = mkOption {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options = {
Addresses.API = mkOption {
type = types.oneOf [ types.str (types.listOf types.str) ];
Addresses.API = lib.mkOption {
type = lib.types.oneOf [ lib.types.str (lib.types.listOf lib.types.str) ];
default = [ ];
description = ''
Multiaddr or array of multiaddrs describing the address to serve the local HTTP API on.
@ -180,14 +179,14 @@ in
'';
};
Addresses.Gateway = mkOption {
type = types.oneOf [ types.str (types.listOf types.str) ];
Addresses.Gateway = lib.mkOption {
type = lib.types.oneOf [ lib.types.str (lib.types.listOf lib.types.str) ];
default = "/ip4/127.0.0.1/tcp/8080";
description = "Where the IPFS Gateway can be reached";
};
Addresses.Swarm = mkOption {
type = types.listOf types.str;
Addresses.Swarm = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"/ip4/0.0.0.0/tcp/4001"
"/ip6/::/tcp/4001"
@ -199,14 +198,14 @@ in
description = "Where Kubo listens for incoming p2p connections";
};
Mounts.IPFS = mkOption {
type = types.str;
Mounts.IPFS = lib.mkOption {
type = lib.types.str;
default = "/ipfs";
description = "Where to mount the IPFS namespace to";
};
Mounts.IPNS = mkOption {
type = types.str;
Mounts.IPNS = lib.mkOption {
type = lib.types.str;
default = "/ipns";
description = "Where to mount the IPNS namespace to";
};
@ -230,29 +229,29 @@ in
};
extraFlags = mkOption {
type = types.listOf types.str;
extraFlags = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Extra flags passed to the Kubo daemon";
default = [ ];
};
localDiscovery = mkOption {
type = types.bool;
localDiscovery = lib.mkOption {
type = lib.types.bool;
description = ''Whether to enable local discovery for the Kubo daemon.
This will allow Kubo to scan ports on your local network. Some hosting services will ban you if you do this.
'';
default = false;
};
serviceFdlimit = mkOption {
type = types.nullOr types.int;
serviceFdlimit = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "The fdlimit for the Kubo systemd unit or `null` to have the daemon attempt to manage it";
example = 64 * 1024;
};
startWhenNeeded = mkOption {
type = types.bool;
startWhenNeeded = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to use socket activation to start Kubo when needed.";
};
@ -262,7 +261,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = !builtins.hasAttr "Identity" cfg.settings;
@ -288,14 +287,14 @@ in
environment.variables.IPFS_PATH = fakeKuboRepo;
# https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes
boot.kernel.sysctl."net.core.rmem_max" = mkDefault 2500000;
boot.kernel.sysctl."net.core.wmem_max" = mkDefault 2500000;
boot.kernel.sysctl."net.core.rmem_max" = lib.mkDefault 2500000;
boot.kernel.sysctl."net.core.wmem_max" = lib.mkDefault 2500000;
programs.fuse = mkIf cfg.autoMount {
programs.fuse = lib.mkIf cfg.autoMount {
userAllowOther = true;
};
users.users = mkIf (cfg.user == "ipfs") {
users.users = lib.mkIf (cfg.user == "ipfs") {
ipfs = {
group = cfg.group;
home = cfg.dataDir;
@ -308,7 +307,7 @@ in
};
};
users.groups = mkIf (cfg.group == "ipfs") {
users.groups = lib.mkIf (cfg.group == "ipfs") {
ipfs.gid = config.ids.gids.ipfs;
};
@ -316,8 +315,8 @@ in
defaultConfig = { inherit (cfg) user group; };
in {
${cfg.dataDir}.d = defaultConfig;
${cfg.settings.Mounts.IPFS}.d = mkIf (cfg.autoMount) defaultConfig;
${cfg.settings.Mounts.IPNS}.d = mkIf (cfg.autoMount) defaultConfig;
${cfg.settings.Mounts.IPFS}.d = lib.mkIf (cfg.autoMount) defaultConfig;
${cfg.settings.Mounts.IPNS}.d = lib.mkIf (cfg.autoMount) defaultConfig;
};
# The hardened systemd unit breaks the fuse-mount function according to documentation in the unit file itself
@ -325,7 +324,7 @@ in
then [ cfg.package.systemd_unit ]
else [ cfg.package.systemd_unit_hardened ];
services.kubo.settings = mkIf cfg.autoMount {
services.kubo.settings = lib.mkIf cfg.autoMount {
Mounts.FuseAllowOther = lib.mkDefault true;
};
@ -339,7 +338,7 @@ in
else
# After an unclean shutdown this file may exist which will cause the config command to attempt to talk to the daemon. This will hang forever if systemd is holding our sockets open.
rm -vf "$IPFS_PATH/api"
'' + optionalString cfg.autoMigrate ''
'' + lib.optionalString cfg.autoMigrate ''
${pkgs.kubo-migrator}/bin/fs-repo-migrations -to '${cfg.package.repoVersion}' -y
'' + ''
fi
@ -356,7 +355,7 @@ in
# change when the changes are applied. Whyyyyyy.....
ipfs --offline config replace -
'';
postStop = mkIf cfg.autoMount ''
postStop = lib.mkIf cfg.autoMount ''
# After an unclean shutdown the fuse mounts at cfg.settings.Mounts.IPFS and cfg.settings.Mounts.IPNS are locked
umount --quiet '${cfg.settings.Mounts.IPFS}' '${cfg.settings.Mounts.IPNS}' || true
'';
@ -365,11 +364,11 @@ in
User = cfg.user;
Group = cfg.group;
StateDirectory = "";
ReadWritePaths = optionals (!cfg.autoMount) [ "" cfg.dataDir ];
ReadWritePaths = lib.optionals (!cfg.autoMount) [ "" cfg.dataDir ];
# Make sure the socket units are started before ipfs.service
Sockets = [ "ipfs-gateway.socket" "ipfs-api.socket" ];
} // optionalAttrs (cfg.serviceFdlimit != null) { LimitNOFILE = cfg.serviceFdlimit; };
} // optionalAttrs (!cfg.startWhenNeeded) {
} // lib.optionalAttrs (cfg.serviceFdlimit != null) { LimitNOFILE = cfg.serviceFdlimit; };
} // lib.optionalAttrs (!cfg.startWhenNeeded) {
wantedBy = [ "default.target" ];
};
@ -402,31 +401,31 @@ in
};
imports = [
(mkRenamedOptionModule [ "services" "ipfs" "enable" ] [ "services" "kubo" "enable" ])
(mkRenamedOptionModule [ "services" "ipfs" "package" ] [ "services" "kubo" "package" ])
(mkRenamedOptionModule [ "services" "ipfs" "user" ] [ "services" "kubo" "user" ])
(mkRenamedOptionModule [ "services" "ipfs" "group" ] [ "services" "kubo" "group" ])
(mkRenamedOptionModule [ "services" "ipfs" "dataDir" ] [ "services" "kubo" "dataDir" ])
(mkRenamedOptionModule [ "services" "ipfs" "defaultMode" ] [ "services" "kubo" "defaultMode" ])
(mkRenamedOptionModule [ "services" "ipfs" "autoMount" ] [ "services" "kubo" "autoMount" ])
(mkRenamedOptionModule [ "services" "ipfs" "autoMigrate" ] [ "services" "kubo" "autoMigrate" ])
(mkRenamedOptionModule [ "services" "ipfs" "ipfsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPFS" ])
(mkRenamedOptionModule [ "services" "ipfs" "ipnsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPNS" ])
(mkRenamedOptionModule [ "services" "ipfs" "gatewayAddress" ] [ "services" "kubo" "settings" "Addresses" "Gateway" ])
(mkRenamedOptionModule [ "services" "ipfs" "apiAddress" ] [ "services" "kubo" "settings" "Addresses" "API" ])
(mkRenamedOptionModule [ "services" "ipfs" "swarmAddress" ] [ "services" "kubo" "settings" "Addresses" "Swarm" ])
(mkRenamedOptionModule [ "services" "ipfs" "enableGC" ] [ "services" "kubo" "enableGC" ])
(mkRenamedOptionModule [ "services" "ipfs" "emptyRepo" ] [ "services" "kubo" "emptyRepo" ])
(mkRenamedOptionModule [ "services" "ipfs" "extraConfig" ] [ "services" "kubo" "settings" ])
(mkRenamedOptionModule [ "services" "ipfs" "extraFlags" ] [ "services" "kubo" "extraFlags" ])
(mkRenamedOptionModule [ "services" "ipfs" "localDiscovery" ] [ "services" "kubo" "localDiscovery" ])
(mkRenamedOptionModule [ "services" "ipfs" "serviceFdlimit" ] [ "services" "kubo" "serviceFdlimit" ])
(mkRenamedOptionModule [ "services" "ipfs" "startWhenNeeded" ] [ "services" "kubo" "startWhenNeeded" ])
(mkRenamedOptionModule [ "services" "kubo" "extraConfig" ] [ "services" "kubo" "settings" ])
(mkRenamedOptionModule [ "services" "kubo" "gatewayAddress" ] [ "services" "kubo" "settings" "Addresses" "Gateway" ])
(mkRenamedOptionModule [ "services" "kubo" "apiAddress" ] [ "services" "kubo" "settings" "Addresses" "API" ])
(mkRenamedOptionModule [ "services" "kubo" "swarmAddress" ] [ "services" "kubo" "settings" "Addresses" "Swarm" ])
(mkRenamedOptionModule [ "services" "kubo" "ipfsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPFS" ])
(mkRenamedOptionModule [ "services" "kubo" "ipnsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPNS" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "enable" ] [ "services" "kubo" "enable" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "package" ] [ "services" "kubo" "package" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "user" ] [ "services" "kubo" "user" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "group" ] [ "services" "kubo" "group" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "dataDir" ] [ "services" "kubo" "dataDir" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "defaultMode" ] [ "services" "kubo" "defaultMode" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "autoMount" ] [ "services" "kubo" "autoMount" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "autoMigrate" ] [ "services" "kubo" "autoMigrate" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "ipfsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPFS" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "ipnsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPNS" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "gatewayAddress" ] [ "services" "kubo" "settings" "Addresses" "Gateway" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "apiAddress" ] [ "services" "kubo" "settings" "Addresses" "API" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "swarmAddress" ] [ "services" "kubo" "settings" "Addresses" "Swarm" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "enableGC" ] [ "services" "kubo" "enableGC" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "emptyRepo" ] [ "services" "kubo" "emptyRepo" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "extraConfig" ] [ "services" "kubo" "settings" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "extraFlags" ] [ "services" "kubo" "extraFlags" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "localDiscovery" ] [ "services" "kubo" "localDiscovery" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "serviceFdlimit" ] [ "services" "kubo" "serviceFdlimit" ])
(lib.mkRenamedOptionModule [ "services" "ipfs" "startWhenNeeded" ] [ "services" "kubo" "startWhenNeeded" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "extraConfig" ] [ "services" "kubo" "settings" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "gatewayAddress" ] [ "services" "kubo" "settings" "Addresses" "Gateway" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "apiAddress" ] [ "services" "kubo" "settings" "Addresses" "API" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "swarmAddress" ] [ "services" "kubo" "settings" "Addresses" "Swarm" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "ipfsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPFS" ])
(lib.mkRenamedOptionModule [ "services" "kubo" "ipnsMountDir" ] [ "services" "kubo" "settings" "Mounts" "IPNS" ])
];
}

View File

@ -1,18 +1,15 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.litestream;
settingsFormat = pkgs.formats.yaml {};
in
{
options.services.litestream = {
enable = mkEnableOption "litestream";
enable = lib.mkEnableOption "litestream";
package = mkPackageOption pkgs "litestream" { };
package = lib.mkPackageOption pkgs "litestream" { };
settings = mkOption {
settings = lib.mkOption {
description = ''
See the [documentation](https://litestream.io/reference/config/).
'';
@ -31,8 +28,8 @@ in
};
};
environmentFile = mkOption {
type = types.nullOr types.path;
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = "/run/secrets/litestream";
description = ''
@ -61,7 +58,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc = {
"litestream.yml" = {
@ -74,7 +71,7 @@ in
wantedBy = [ "multi-user.target" ];
after = [ "networking.target" ];
serviceConfig = {
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
ExecStart = "${cfg.package}/bin/litestream replicate";
Restart = "always";
User = "litestream";

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.moosefs;
@ -9,14 +6,14 @@ let
settingsFormat = let
listSep = " ";
allowedTypes = with types; [ bool int float str ];
allowedTypes = with lib.types; [ bool int float str ];
valueToString = val:
if isList val then concatStringsSep listSep (map (x: valueToString x) val)
else if isBool val then (if val then "1" else "0")
if lib.isList val then lib.concatStringsSep listSep (map (x: valueToString x) val)
else if lib.isBool val then (if val then "1" else "0")
else toString val;
in {
type = with types; let
type = with lib.types; let
valueType = oneOf ([
(listOf valueType)
] ++ allowedTypes) // {
@ -72,24 +69,24 @@ in {
options = {
services.moosefs = {
masterHost = mkOption {
type = types.str;
masterHost = lib.mkOption {
type = lib.types.str;
default = null;
description = "IP or DNS name of master host.";
};
runAsUser = mkOption {
type = types.bool;
runAsUser = lib.mkOption {
type = lib.types.bool;
default = true;
example = true;
description = "Run daemons as user moosefs instead of root.";
};
client.enable = mkEnableOption "Moosefs client";
client.enable = lib.mkEnableOption "Moosefs client";
master = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
description = ''
Enable Moosefs master daemon.
@ -99,8 +96,8 @@ in {
default = false;
};
exports = mkOption {
type = with types; listOf str;
exports = lib.mkOption {
type = with lib.types; listOf str;
default = null;
description = "Paths to export (see mfsexports.cfg).";
example = [
@ -109,18 +106,18 @@ in {
];
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
description = "Whether to automatically open the necessary ports in the firewall.";
default = false;
};
settings = mkOption {
type = types.submodule {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.DATA_PATH = mkOption {
type = types.str;
options.DATA_PATH = lib.mkOption {
type = lib.types.str;
default = "/var/lib/mfs";
description = "Data storage directory.";
};
@ -131,14 +128,14 @@ in {
};
metalogger = {
enable = mkEnableOption "Moosefs metalogger daemon";
enable = lib.mkEnableOption "Moosefs metalogger daemon";
settings = mkOption {
type = types.submodule {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.DATA_PATH = mkOption {
type = types.str;
options.DATA_PATH = lib.mkOption {
type = lib.types.str;
default = "/var/lib/mfs";
description = "Data storage directory";
};
@ -149,27 +146,27 @@ in {
};
chunkserver = {
enable = mkEnableOption "Moosefs chunkserver daemon";
enable = lib.mkEnableOption "Moosefs chunkserver daemon";
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
description = "Whether to automatically open the necessary ports in the firewall.";
default = false;
};
hdds = mkOption {
type = with types; listOf str;
hdds = lib.mkOption {
type = with lib.types; listOf str;
default = null;
description = "Mount points to be used by chunkserver for storage (see mfshdd.cfg).";
example = [ "/mnt/hdd1" ];
};
settings = mkOption {
type = types.submodule {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.DATA_PATH = mkOption {
type = types.str;
options.DATA_PATH = lib.mkOption {
type = lib.types.str;
default = "/var/lib/mfs";
description = "Directory for lock file.";
};
@ -183,33 +180,33 @@ in {
###### implementation
config = mkIf ( cfg.client.enable || cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) {
config = lib.mkIf ( cfg.client.enable || cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) {
warnings = [ ( mkIf (!cfg.runAsUser) "Running moosefs services as root is not recommended.") ];
warnings = [ ( lib.mkIf (!cfg.runAsUser) "Running moosefs services as root is not recommended.") ];
# Service settings
services.moosefs = {
master.settings = mkIf cfg.master.enable {
master.settings = lib.mkIf cfg.master.enable {
WORKING_USER = mfsUser;
EXPORTS_FILENAME = toString ( pkgs.writeText "mfsexports.cfg"
(concatStringsSep "\n" cfg.master.exports));
(lib.concatStringsSep "\n" cfg.master.exports));
};
metalogger.settings = mkIf cfg.metalogger.enable {
metalogger.settings = lib.mkIf cfg.metalogger.enable {
WORKING_USER = mfsUser;
MASTER_HOST = cfg.masterHost;
};
chunkserver.settings = mkIf cfg.chunkserver.enable {
chunkserver.settings = lib.mkIf cfg.chunkserver.enable {
WORKING_USER = mfsUser;
MASTER_HOST = cfg.masterHost;
HDD_CONF_FILENAME = toString ( pkgs.writeText "mfshdd.cfg"
(concatStringsSep "\n" cfg.chunkserver.hdds));
(lib.concatStringsSep "\n" cfg.chunkserver.hdds));
};
};
# Create system user account for daemons
users = mkIf ( cfg.runAsUser && ( cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) ) {
users = lib.mkIf ( cfg.runAsUser && ( cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) ) {
users.moosefs = {
isSystemUser = true;
description = "moosefs daemon user";
@ -228,22 +225,22 @@ in {
# Ensure storage directories exist
systemd.tmpfiles.rules =
optional cfg.master.enable "d ${cfg.master.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
++ optional cfg.metalogger.enable "d ${cfg.metalogger.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
++ optional cfg.chunkserver.enable "d ${cfg.chunkserver.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}";
lib.optional cfg.master.enable "d ${cfg.master.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
++ lib.optional cfg.metalogger.enable "d ${cfg.metalogger.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
++ lib.optional cfg.chunkserver.enable "d ${cfg.chunkserver.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}";
# Service definitions
systemd.services.mfs-master = mkIf cfg.master.enable
systemd.services.mfs-master = lib.mkIf cfg.master.enable
( systemdService "master" {
TimeoutStartSec = 1800;
TimeoutStopSec = 1800;
Restart = "no";
} masterCfg );
systemd.services.mfs-metalogger = mkIf cfg.metalogger.enable
systemd.services.mfs-metalogger = lib.mkIf cfg.metalogger.enable
( systemdService "metalogger" { Restart = "on-abnormal"; } metaloggerCfg );
systemd.services.mfs-chunkserver = mkIf cfg.chunkserver.enable
systemd.services.mfs-chunkserver = lib.mkIf cfg.chunkserver.enable
( systemdService "chunkserver" { Restart = "on-abnormal"; } chunkserverCfg );
};
}

View File

@ -1,7 +1,4 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.netatalk;
settingsFormat = pkgs.formats.ini { };
@ -10,15 +7,15 @@ in {
options = {
services.netatalk = {
enable = mkEnableOption "the Netatalk AFP fileserver";
enable = lib.mkEnableOption "the Netatalk AFP fileserver";
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 548;
description = "TCP port to be used for AFP.";
};
settings = mkOption {
settings = lib.mkOption {
inherit (settingsFormat) type;
default = { };
example = {
@ -38,8 +35,8 @@ in {
'';
};
extmap = mkOption {
type = types.lines;
extmap = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
File name extension mappings.
@ -51,14 +48,14 @@ in {
};
imports = (map (option:
mkRemovedOptionModule [ "services" "netatalk" option ]
lib.mkRemovedOptionModule [ "services" "netatalk" option ]
"This option was removed in favor of `services.netatalk.settings`.") [
"extraConfig"
"homes"
"volumes"
]);
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.netatalk.settings.Global = {
"afp port" = toString cfg.port;

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.nfs.server;
@ -12,8 +9,8 @@ in
{
imports = [
(mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ])
(mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ])
(lib.mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ])
(lib.mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ])
];
###### interface
@ -23,24 +20,24 @@ in
services.nfs = {
server = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the kernel's NFS server.
'';
};
extraNfsdConfig = mkOption {
type = types.str;
extraNfsdConfig = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Extra configuration options for the [nfsd] section of /etc/nfs.conf.
'';
};
exports = mkOption {
type = types.lines;
exports = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Contents of the /etc/exports file. See
@ -48,8 +45,8 @@ in
'';
};
hostName = mkOption {
type = types.nullOr types.str;
hostName = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Hostname or address on which NFS requests will be accepted.
@ -58,22 +55,22 @@ in
'';
};
nproc = mkOption {
type = types.int;
nproc = lib.mkOption {
type = lib.types.int;
default = 8;
description = ''
Number of NFS server threads. Defaults to the recommended value of 8.
'';
};
createMountPoints = mkOption {
type = types.bool;
createMountPoints = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to create the mount points in the exports file at startup time.";
};
mountdPort = mkOption {
type = types.nullOr types.int;
mountdPort = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 4002;
description = ''
@ -81,8 +78,8 @@ in
'';
};
lockdPort = mkOption {
type = types.nullOr types.int;
lockdPort = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 4001;
description = ''
@ -92,8 +89,8 @@ in
'';
};
statdPort = mkOption {
type = types.nullOr types.int;
statdPort = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 4000;
description = ''
@ -111,7 +108,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.rpcbind.enable = true;
@ -137,7 +134,7 @@ in
''
mkdir -p /var/lib/nfs
${optionalString cfg.createMountPoints
${lib.optionalString cfg.createMountPoints
''
# create export directories:
# skip comments, take first col which may either be a quoted

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ...} :
with lib;
let
cfg = config.services.orangefs.client;
@ -10,15 +7,15 @@ in {
options = {
services.orangefs.client = {
enable = mkEnableOption "OrangeFS client daemon";
enable = lib.mkEnableOption "OrangeFS client daemon";
extraOptions = mkOption {
type = with types; listOf str;
extraOptions = lib.mkOption {
type = with lib.types; listOf str;
default = [];
description = "Extra command line options for pvfs2-client.";
};
fileSystems = mkOption {
fileSystems = lib.mkOption {
description = ''
The orangefs file systems to be mounted.
This option is preferred over using {option}`fileSystems` directly since
@ -30,23 +27,23 @@ in {
target = "tcp://server:3334/orangefs";
}];
type = with types; listOf (submodule ({ ... } : {
type = with lib.types; listOf (submodule ({ ... } : {
options = {
mountPoint = mkOption {
type = types.str;
mountPoint = lib.mkOption {
type = lib.types.str;
default = "/orangefs";
description = "Mount point.";
};
options = mkOption {
type = with types; listOf str;
options = lib.mkOption {
type = with lib.types; listOf str;
default = [];
description = "Mount options";
};
target = mkOption {
type = types.str;
target = lib.mkOption {
type = lib.types.str;
example = "tcp://server:3334/orangefs";
description = "Target URL";
};
@ -59,7 +56,7 @@ in {
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.orangefs ];
boot.supportedFilesystems = [ "pvfs2" ];
@ -74,7 +71,7 @@ in {
ExecStart = ''
${pkgs.orangefs}/bin/pvfs2-client-core \
--logtype=syslog ${concatStringsSep " " cfg.extraOptions}
--logtype=syslog ${lib.concatStringsSep " " cfg.extraOptions}
'';
TimeoutStopSec = "120";
@ -87,7 +84,7 @@ in {
bindsTo = [ "orangefs-client.service" ];
wantedBy = [ "remote-fs.target" ];
type = "pvfs2";
options = concatStringsSep "," fs.options;
options = lib.concatStringsSep "," fs.options;
what = fs.target;
where = fs.mountPoint;
}) cfg.fileSystems;

View File

@ -1,19 +1,16 @@
{ config, lib, pkgs, ...} :
with lib;
let
cfg = config.services.orangefs.server;
aliases = mapAttrsToList (alias: url: alias) cfg.servers;
aliases = lib.mapAttrsToList (alias: url: alias) cfg.servers;
# Maximum handle number is 2^63
maxHandle = 9223372036854775806;
# One range of handles for each meta/data instance
handleStep = maxHandle / (length aliases) / 2;
handleStep = maxHandle / (lib.length aliases) / 2;
fileSystems = mapAttrsToList (name: fs: ''
fileSystems = lib.mapAttrsToList (name: fs: ''
<FileSystem>
Name ${name}
ID ${toString fs.id}
@ -22,8 +19,8 @@ let
${fs.extraConfig}
<MetaHandleRanges>
${concatStringsSep "\n" (
imap0 (i: alias:
${lib.concatStringsSep "\n" (
lib.imap0 (i: alias:
let
begin = i * handleStep + 3;
end = begin + handleStep - 1;
@ -32,10 +29,10 @@ let
</MetaHandleRanges>
<DataHandleRanges>
${concatStringsSep "\n" (
imap0 (i: alias:
${lib.concatStringsSep "\n" (
lib.imap0 (i: alias:
let
begin = i * handleStep + 3 + (length aliases) * handleStep;
begin = i * handleStep + 3 + (lib.length aliases) * handleStep;
end = begin + handleStep - 1;
in "Range ${alias} ${toString begin}-${toString end}") aliases
)}
@ -56,17 +53,17 @@ let
DataStorageSpace ${cfg.dataStorageSpace}
MetaDataStorageSpace ${cfg.metadataStorageSpace}
BMIModules ${concatStringsSep "," cfg.BMIModules}
BMIModules ${lib.concatStringsSep "," cfg.BMIModules}
${cfg.extraDefaults}
</Defaults>
${cfg.extraConfig}
<Aliases>
${concatStringsSep "\n" (mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)}
${lib.concatStringsSep "\n" (lib.mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)}
</Aliases>
${concatStringsSep "\n" fileSystems}
${lib.concatStringsSep "\n" fileSystems}
'';
in {
@ -74,49 +71,49 @@ in {
options = {
services.orangefs.server = {
enable = mkEnableOption "OrangeFS server";
enable = lib.mkEnableOption "OrangeFS server";
logType = mkOption {
type = with types; enum [ "file" "syslog" ];
logType = lib.mkOption {
type = with lib.types; enum [ "file" "syslog" ];
default = "syslog";
description = "Destination for log messages.";
};
dataStorageSpace = mkOption {
type = types.nullOr types.str;
dataStorageSpace = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/data/storage";
description = "Directory for data storage.";
};
metadataStorageSpace = mkOption {
type = types.nullOr types.str;
metadataStorageSpace = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/data/meta";
description = "Directory for meta data storage.";
};
BMIModules = mkOption {
type = with types; listOf str;
BMIModules = lib.mkOption {
type = with lib.types; listOf str;
default = [ "bmi_tcp" ];
example = [ "bmi_tcp" "bmi_ib"];
description = "List of BMI modules to load.";
};
extraDefaults = mkOption {
type = types.lines;
extraDefaults = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config for `<Defaults>` section.";
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config for the global section.";
};
servers = mkOption {
type = with types; attrsOf types.str;
servers = lib.mkOption {
type = with lib.types; attrsOf lib.types.str;
default = {};
example = {
node1 = "tcp://node1:3334";
@ -125,12 +122,12 @@ in {
description = "URLs for storage server including port. The attribute names define the server alias.";
};
fileSystems = mkOption {
fileSystems = lib.mkOption {
description = ''
These options will create the `<FileSystem>` sections of config file.
'';
default = { orangefs = {}; };
example = literalExpression ''
example = lib.literalExpression ''
{
fs1 = {
id = 101;
@ -141,40 +138,40 @@ in {
};
}
'';
type = with types; attrsOf (submodule ({ ... } : {
type = with lib.types; attrsOf (submodule ({ ... } : {
options = {
id = mkOption {
type = types.int;
id = lib.mkOption {
type = lib.types.int;
default = 1;
description = "File system ID (must be unique within configuration).";
};
rootHandle = mkOption {
type = types.int;
rootHandle = lib.mkOption {
type = lib.types.int;
default = 3;
description = "File system root ID.";
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config for `<FileSystem>` section.";
};
troveSyncMeta = mkOption {
type = types.bool;
troveSyncMeta = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Sync meta data.";
};
troveSyncData = mkOption {
type = types.bool;
troveSyncData = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Sync data.";
};
extraStorageHints = mkOption {
type = types.lines;
extraStorageHints = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config for `<StorageHints>` section.";
};
@ -186,7 +183,7 @@ in {
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.orangefs ];
# orangefs daemon will run as user

View File

@ -1,7 +1,4 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.rsyncd;
settingsFormat = pkgs.formats.ini { };
@ -10,15 +7,15 @@ in {
options = {
services.rsyncd = {
enable = mkEnableOption "the rsync daemon";
enable = lib.mkEnableOption "the rsync daemon";
port = mkOption {
port = lib.mkOption {
default = 873;
type = types.port;
type = lib.types.port;
description = "TCP port the daemon will listen on.";
};
settings = mkOption {
settings = lib.mkOption {
inherit (settingsFormat) type;
default = { };
example = {
@ -45,9 +42,9 @@ in {
'';
};
socketActivated = mkOption {
socketActivated = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = "If enabled Rsync will be socket-activated rather than run persistently.";
};
@ -55,7 +52,7 @@ in {
};
imports = (map (option:
mkRemovedOptionModule [ "services" "rsyncd" option ]
lib.mkRemovedOptionModule [ "services" "rsyncd" option ]
"This option was removed in favor of `services.rsyncd.settings`.") [
"address"
"extraConfig"
@ -64,7 +61,7 @@ in {
"group"
]);
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.rsyncd.settings.global.port = toString cfg.port;

View File

@ -1,65 +1,62 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.samba-wsdd;
in {
options = {
services.samba-wsdd = {
enable = mkEnableOption ''
enable = lib.mkEnableOption ''
Web Services Dynamic Discovery host daemon. This enables (Samba) hosts, like your local NAS device,
to be found by Web Service Discovery Clients like Windows
'';
interface = mkOption {
type = types.nullOr types.str;
interface = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "eth0";
description = "Interface or address to use.";
};
hoplimit = mkOption {
type = types.nullOr types.int;
hoplimit = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 2;
description = "Hop limit for multicast packets (default = 1).";
};
openFirewall = mkOption {
openFirewall = lib.mkOption {
description = ''
Whether to open the required firewall ports in the firewall.
'';
default = false;
type = lib.types.bool;
};
workgroup = mkOption {
type = types.nullOr types.str;
workgroup = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "HOME";
description = "Set workgroup name (default WORKGROUP).";
};
hostname = mkOption {
type = types.nullOr types.str;
hostname = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "FILESERVER";
description = "Override (NetBIOS) hostname to be used (default hostname).";
};
domain = mkOption {
type = types.nullOr types.str;
domain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Set domain name (disables workgroup).";
};
discovery = mkOption {
type = types.bool;
discovery = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable discovery operation mode.";
};
listen = mkOption {
type = types.str;
listen = lib.mkOption {
type = lib.types.str;
default = "/run/wsdd/wsdd.sock";
description = "Listen on path or localhost port in discovery mode.";
};
extraOptions = mkOption {
type = types.listOf types.str;
extraOptions = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "--shortlog" ];
example = [ "--verbose" "--no-http" "--ipv4only" "--no-host" ];
description = "Additional wsdd options.";
@ -67,7 +64,7 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.wsdd ];
@ -79,13 +76,13 @@ in {
DynamicUser = true;
Type = "simple";
ExecStart = ''
${pkgs.wsdd}/bin/wsdd ${optionalString (cfg.interface != null) "--interface '${cfg.interface}'"} \
${optionalString (cfg.hoplimit != null) "--hoplimit '${toString cfg.hoplimit}'"} \
${optionalString (cfg.workgroup != null) "--workgroup '${cfg.workgroup}'"} \
${optionalString (cfg.hostname != null) "--hostname '${cfg.hostname}'"} \
${optionalString (cfg.domain != null) "--domain '${cfg.domain}'"} \
${optionalString cfg.discovery "--discovery --listen '${cfg.listen}'"} \
${escapeShellArgs cfg.extraOptions}
${pkgs.wsdd}/bin/wsdd ${lib.optionalString (cfg.interface != null) "--interface '${cfg.interface}'"} \
${lib.optionalString (cfg.hoplimit != null) "--hoplimit '${toString cfg.hoplimit}'"} \
${lib.optionalString (cfg.workgroup != null) "--workgroup '${cfg.workgroup}'"} \
${lib.optionalString (cfg.hostname != null) "--hostname '${cfg.hostname}'"} \
${lib.optionalString (cfg.domain != null) "--domain '${cfg.domain}'"} \
${lib.optionalString cfg.discovery "--discovery --listen '${cfg.listen}'"} \
${lib.escapeShellArgs cfg.extraOptions}
'';
# Runtime directory and mode
RuntimeDirectory = "wsdd";
@ -121,7 +118,7 @@ in {
};
};
networking.firewall = mkIf cfg.openFirewall {
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ 5357 ];
allowedUDPPorts = [ 3702 ];
};

View File

@ -1,12 +1,9 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.samba;
settingsFormat = pkgs.formats.ini {
listToValue = lib.concatMapStringsSep " " (generators.mkValueStringDefault { });
listToValue = lib.concatMapStringsSep " " (lib.generators.mkValueStringDefault { });
};
# Ensure the global section is always first
globalConfigFile = settingsFormat.generate "smb-global.conf" { global = cfg.settings.global; };
@ -23,8 +20,8 @@ in
};
imports = [
(mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
(mkRemovedOptionModule [ "services" "samba" "syncPasswordsByPam" ] "This option has been removed by upstream, see https://bugzilla.samba.org/show_bug.cgi?id=10669#c10")
(lib.mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
(lib.mkRemovedOptionModule [ "services" "samba" "syncPasswordsByPam" ] "This option has been removed by upstream, see https://bugzilla.samba.org/show_bug.cgi?id=10669#c10")
(lib.mkRemovedOptionModule [ "services" "samba" "configText" ] ''
Use services.samba.settings instead.
@ -166,7 +163,7 @@ in
###### implementation
config = mkMerge
config = lib.mkMerge
[ { assertions =
[ { assertion = cfg.nsswins -> cfg.winbindd.enable;
message = "If services.samba.nsswins is enabled, then services.samba.winbindd.enable must also be enabled";
@ -177,8 +174,8 @@ in
(lib.mkIf cfg.enable {
environment.etc."samba/smb.conf".source = configFile;
system.nssModules = optional cfg.nsswins cfg.package;
system.nssDatabases.hosts = optional cfg.nsswins "wins";
system.nssModules = lib.optional cfg.nsswins cfg.package;
system.nssDatabases.hosts = lib.optional cfg.nsswins "wins";
systemd = {
slices.system-samba = {
@ -210,8 +207,8 @@ in
setuid = true;
};
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 139 445 ];
networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ 137 138 ];
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 139 445 ];
networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [ 137 138 ];
})
(lib.mkIf (cfg.enable && cfg.nmbd.enable) {

View File

@ -1,57 +1,55 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.tahoe;
in
{
options.services.tahoe = {
introducers = mkOption {
introducers = lib.mkOption {
default = {};
type = with types; attrsOf (submodule {
type = with lib.types; attrsOf (submodule {
options = {
nickname = mkOption {
type = types.str;
nickname = lib.mkOption {
type = lib.types.str;
description = ''
The nickname of this Tahoe introducer.
'';
};
tub.port = mkOption {
tub.port = lib.mkOption {
default = 3458;
type = types.port;
type = lib.types.port;
description = ''
The port on which the introducer will listen.
'';
};
tub.location = mkOption {
tub.location = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The external location that the introducer should listen on.
If specified, the port should be included.
'';
};
package = mkPackageOption pkgs "tahoelafs" { };
package = lib.mkPackageOption pkgs "tahoelafs" { };
};
});
description = ''
The Tahoe introducers.
'';
};
nodes = mkOption {
nodes = lib.mkOption {
default = {};
type = with types; attrsOf (submodule {
type = with lib.types; attrsOf (submodule {
options = {
nickname = mkOption {
type = types.str;
nickname = lib.mkOption {
type = lib.types.str;
description = ''
The nickname of this Tahoe node.
'';
};
tub.port = mkOption {
tub.port = lib.mkOption {
default = 3457;
type = types.port;
type = lib.types.port;
description = ''
The port on which the tub will listen.
@ -59,9 +57,9 @@ in
system to listen on a different port.
'';
};
tub.location = mkOption {
tub.location = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The external location that the node should listen on.
@ -71,9 +69,9 @@ in
If specified, the port should be included.
'';
};
web.port = mkOption {
web.port = lib.mkOption {
default = 3456;
type = types.port;
type = lib.types.port;
description = ''
The port on which the Web server will listen.
@ -81,59 +79,59 @@ in
listen on a different port.
'';
};
client.introducer = mkOption {
client.introducer = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The furl for a Tahoe introducer node.
Like all furls, keep this safe and don't share it.
'';
};
client.helper = mkOption {
client.helper = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The furl for a Tahoe helper node.
Like all furls, keep this safe and don't share it.
'';
};
client.shares.needed = mkOption {
client.shares.needed = lib.mkOption {
default = 3;
type = types.int;
type = lib.types.int;
description = ''
The number of shares required to reconstitute a file.
'';
};
client.shares.happy = mkOption {
client.shares.happy = lib.mkOption {
default = 7;
type = types.int;
type = lib.types.int;
description = ''
The number of distinct storage nodes required to store
a file.
'';
};
client.shares.total = mkOption {
client.shares.total = lib.mkOption {
default = 10;
type = types.int;
type = lib.types.int;
description = ''
The number of shares required to store a file.
'';
};
storage.enable = mkEnableOption "storage service";
storage.reservedSpace = mkOption {
storage.enable = lib.mkEnableOption "storage service";
storage.reservedSpace = lib.mkOption {
default = "1G";
type = types.str;
type = lib.types.str;
description = ''
The amount of filesystem space to not use for storage.
'';
};
helper.enable = mkEnableOption "helper service";
sftpd.enable = mkEnableOption "SFTP service";
sftpd.port = mkOption {
helper.enable = lib.mkEnableOption "helper service";
sftpd.enable = lib.mkEnableOption "SFTP service";
sftpd.port = lib.mkOption {
default = null;
type = types.nullOr types.int;
type = lib.types.nullOr lib.types.int;
description = ''
The port on which the SFTP server will listen.
@ -141,35 +139,35 @@ in
daemon to listen on a different port.
'';
};
sftpd.hostPublicKeyFile = mkOption {
sftpd.hostPublicKeyFile = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = ''
Path to the SSH host public key.
'';
};
sftpd.hostPrivateKeyFile = mkOption {
sftpd.hostPrivateKeyFile = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = ''
Path to the SSH host private key.
'';
};
sftpd.accounts.file = mkOption {
sftpd.accounts.file = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = ''
Path to the accounts file.
'';
};
sftpd.accounts.url = mkOption {
sftpd.accounts.url = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
URL of the accounts server.
'';
};
package = mkPackageOption pkgs "tahoelafs" { };
package = lib.mkPackageOption pkgs "tahoelafs" { };
};
});
description = ''
@ -177,11 +175,11 @@ in
'';
};
};
config = mkMerge [
(mkIf (cfg.introducers != {}) {
config = lib.mkMerge [
(lib.mkIf (cfg.introducers != {}) {
environment = {
etc = flip mapAttrs' cfg.introducers (node: settings:
nameValuePair "tahoe-lafs/introducer-${node}.cfg" {
etc = lib.flip lib.mapAttrs' cfg.introducers (node: settings:
lib.nameValuePair "tahoe-lafs/introducer-${node}.cfg" {
mode = "0444";
text = ''
# This configuration is generated by Nix. Edit at your own
@ -190,25 +188,25 @@ in
[node]
nickname = ${settings.nickname}
tub.port = ${toString settings.tub.port}
${optionalString (settings.tub.location != null)
${lib.optionalString (settings.tub.location != null)
"tub.location = ${settings.tub.location}"}
'';
});
# Actually require Tahoe, so that we will have it installed.
systemPackages = flip mapAttrsToList cfg.introducers (node: settings:
systemPackages = lib.flip lib.mapAttrsToList cfg.introducers (node: settings:
settings.package
);
};
# Open up the firewall.
# networking.firewall.allowedTCPPorts = flip mapAttrsToList cfg.introducers
# networking.firewall.allowedTCPPorts = lib.flip lib.mapAttrsToList cfg.introducers
# (node: settings: settings.tub.port);
systemd.services = flip mapAttrs' cfg.introducers (node: settings:
systemd.services = lib.flip lib.mapAttrs' cfg.introducers (node: settings:
let
pidfile = "/run/tahoe.introducer-${node}.pid";
# This is a directory, but it has no trailing slash. Tahoe commands
# get antsy when there's a trailing slash.
nodedir = "/var/db/tahoe-lafs/introducer-${node}";
in nameValuePair "tahoe.introducer-${node}" {
in lib.nameValuePair "tahoe.introducer-${node}" {
description = "Tahoe LAFS node ${node}";
wantedBy = [ "multi-user.target" ];
path = [ settings.package ];
@ -242,16 +240,16 @@ in
cp /etc/tahoe-lafs/introducer-"${node}".cfg ${lib.escapeShellArg nodedir}/tahoe.cfg
'';
});
users.users = flip mapAttrs' cfg.introducers (node: _:
nameValuePair "tahoe.introducer-${node}" {
users.users = lib.flip lib.mapAttrs' cfg.introducers (node: _:
lib.nameValuePair "tahoe.introducer-${node}" {
description = "Tahoe node user for introducer ${node}";
isSystemUser = true;
});
})
(mkIf (cfg.nodes != {}) {
(lib.mkIf (cfg.nodes != {}) {
environment = {
etc = flip mapAttrs' cfg.nodes (node: settings:
nameValuePair "tahoe-lafs/${node}.cfg" {
etc = lib.flip lib.mapAttrs' cfg.nodes (node: settings:
lib.nameValuePair "tahoe-lafs/${node}.cfg" {
mode = "0444";
text = ''
# This configuration is generated by Nix. Edit at your own
@ -260,16 +258,16 @@ in
[node]
nickname = ${settings.nickname}
tub.port = ${toString settings.tub.port}
${optionalString (settings.tub.location != null)
${lib.optionalString (settings.tub.location != null)
"tub.location = ${settings.tub.location}"}
# This is a Twisted endpoint. Twisted Web doesn't work on
# non-TCP. ~ C.
web.port = tcp:${toString settings.web.port}
[client]
${optionalString (settings.client.introducer != null)
${lib.optionalString (settings.client.introducer != null)
"introducer.furl = ${settings.client.introducer}"}
${optionalString (settings.client.helper != null)
${lib.optionalString (settings.client.helper != null)
"helper.furl = ${settings.client.helper}"}
shares.needed = ${toString settings.client.shares.needed}
@ -277,41 +275,41 @@ in
shares.total = ${toString settings.client.shares.total}
[storage]
enabled = ${boolToString settings.storage.enable}
enabled = ${lib.boolToString settings.storage.enable}
reserved_space = ${settings.storage.reservedSpace}
[helper]
enabled = ${boolToString settings.helper.enable}
enabled = ${lib.boolToString settings.helper.enable}
[sftpd]
enabled = ${boolToString settings.sftpd.enable}
${optionalString (settings.sftpd.port != null)
enabled = ${lib.boolToString settings.sftpd.enable}
${lib.optionalString (settings.sftpd.port != null)
"port = ${toString settings.sftpd.port}"}
${optionalString (settings.sftpd.hostPublicKeyFile != null)
${lib.optionalString (settings.sftpd.hostPublicKeyFile != null)
"host_pubkey_file = ${settings.sftpd.hostPublicKeyFile}"}
${optionalString (settings.sftpd.hostPrivateKeyFile != null)
${lib.optionalString (settings.sftpd.hostPrivateKeyFile != null)
"host_privkey_file = ${settings.sftpd.hostPrivateKeyFile}"}
${optionalString (settings.sftpd.accounts.file != null)
${lib.optionalString (settings.sftpd.accounts.file != null)
"accounts.file = ${settings.sftpd.accounts.file}"}
${optionalString (settings.sftpd.accounts.url != null)
${lib.optionalString (settings.sftpd.accounts.url != null)
"accounts.url = ${settings.sftpd.accounts.url}"}
'';
});
# Actually require Tahoe, so that we will have it installed.
systemPackages = flip mapAttrsToList cfg.nodes (node: settings:
systemPackages = lib.flip lib.mapAttrsToList cfg.nodes (node: settings:
settings.package
);
};
# Open up the firewall.
# networking.firewall.allowedTCPPorts = flip mapAttrsToList cfg.nodes
# networking.firewall.allowedTCPPorts = lib.flip lib.mapAttrsToList cfg.nodes
# (node: settings: settings.tub.port);
systemd.services = flip mapAttrs' cfg.nodes (node: settings:
systemd.services = lib.flip lib.mapAttrs' cfg.nodes (node: settings:
let
pidfile = "/run/tahoe.${node}.pid";
# This is a directory, but it has no trailing slash. Tahoe commands
# get antsy when there's a trailing slash.
nodedir = "/var/db/tahoe-lafs/${node}";
in nameValuePair "tahoe.${node}" {
in lib.nameValuePair "tahoe.${node}" {
description = "Tahoe LAFS node ${node}";
wantedBy = [ "multi-user.target" ];
path = [ settings.package ];
@ -342,8 +340,8 @@ in
cp /etc/tahoe-lafs/${lib.escapeShellArg node}.cfg ${lib.escapeShellArg nodedir}/tahoe.cfg
'';
});
users.users = flip mapAttrs' cfg.nodes (node: _:
nameValuePair "tahoe.${node}" {
users.users = lib.flip lib.mapAttrs' cfg.nodes (node: _:
lib.nameValuePair "tahoe.${node}" {
description = "Tahoe node user for node ${node}";
isSystemUser = true;
});

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.u9fs;
in
@ -11,14 +8,14 @@ in
services.u9fs = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to run the u9fs 9P server for Unix.";
};
listenStreams = mkOption {
type = types.listOf types.str;
listenStreams = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "564" ];
example = [ "192.168.16.1:564" ];
description = ''
@ -27,14 +24,14 @@ in
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "nobody";
description = "User to run u9fs under.";
};
extraArgs = mkOption {
type = types.str;
extraArgs = lib.mkOption {
type = lib.types.str;
default = "";
example = "-a none";
description = ''
@ -47,7 +44,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd = {
sockets.u9fs = {

View File

@ -1,10 +1,8 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.webdav-server-rs;
format = pkgs.formats.toml { };
settings = recursiveUpdate
settings = lib.recursiveUpdate
{
server.uid = config.users.users."${cfg.user}".uid;
server.gid = config.users.groups."${cfg.group}".gid;
@ -14,27 +12,27 @@ in
{
options = {
services.webdav-server-rs = {
enable = mkEnableOption "WebDAV server";
enable = lib.mkEnableOption "WebDAV server";
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "webdav";
description = "User to run under when setuid is not enabled.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "webdav";
description = "Group to run under when setuid is not enabled.";
};
debug = mkOption {
type = types.bool;
debug = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable debug mode.";
};
settings = mkOption {
settings = lib.mkOption {
type = format.type;
default = { };
description = ''
@ -42,7 +40,7 @@ in
options can be found at
[here](https://github.com/miquels/webdav-server-rs/blob/master/webdav-server.toml).
'';
example = literalExpression ''
example = lib.literalExpression ''
{
server.listen = [ "0.0.0.0:4918" "[::]:4918" ];
accounts = {
@ -75,8 +73,8 @@ in
'';
};
configFile = mkOption {
type = types.path;
configFile = lib.mkOption {
type = lib.types.path;
default = format.generate "webdav-server.toml" settings;
defaultText = "Config file generated from services.webdav-server-rs.settings";
description = ''
@ -88,19 +86,19 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = hasAttr cfg.user config.users.users && config.users.users."${cfg.user}".uid != null;
assertion = lib.hasAttr cfg.user config.users.users && config.users.users."${cfg.user}".uid != null;
message = "users.users.${cfg.user} and users.users.${cfg.user}.uid must be defined.";
}
{
assertion = hasAttr cfg.group config.users.groups && config.users.groups."${cfg.group}".gid != null;
assertion = lib.hasAttr cfg.group config.users.groups && config.users.groups."${cfg.group}".gid != null;
message = "users.groups.${cfg.group} and users.groups.${cfg.group}.gid must be defined.";
}
];
users.users = optionalAttrs (cfg.user == "webdav") {
users.users = lib.optionalAttrs (cfg.user == "webdav") {
webdav = {
description = "WebDAV user";
group = cfg.group;
@ -108,7 +106,7 @@ in
};
};
users.groups = optionalAttrs (cfg.group == "webdav") {
users.groups = lib.optionalAttrs (cfg.group == "webdav") {
webdav.gid = config.ids.gids.webdav;
};
@ -146,5 +144,5 @@ in
};
};
meta.maintainers = with maintainers; [ pmy ];
meta.maintainers = with lib.maintainers; [ pmy ];
}

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.webdav;
format = pkgs.formats.yaml { };
@ -8,21 +6,21 @@ in
{
options = {
services.webdav = {
enable = mkEnableOption "WebDAV server";
enable = lib.mkEnableOption "WebDAV server";
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "webdav";
description = "User account under which WebDAV runs.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "webdav";
description = "Group under which WebDAV runs.";
};
settings = mkOption {
settings = lib.mkOption {
type = format.type;
default = { };
description = ''
@ -36,7 +34,7 @@ in
[EnvironmentFile](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#EnvironmentFile=).
This prevents adding secrets to the world-readable Nix store.
'';
example = literalExpression ''
example = lib.literalExpression ''
{
address = "0.0.0.0";
port = 8080;
@ -53,8 +51,8 @@ in
'';
};
configFile = mkOption {
type = types.path;
configFile = lib.mkOption {
type = lib.types.path;
default = format.generate "webdav.yaml" cfg.settings;
defaultText = "Config file generated from services.webdav.settings";
description = ''
@ -64,8 +62,8 @@ in
example = "/etc/webdav/config.yaml";
};
environmentFile = mkOption {
type = types.nullOr types.path;
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Environment file as defined in {manpage}`systemd.exec(5)`.
@ -74,8 +72,8 @@ in
};
};
config = mkIf cfg.enable {
users.users = mkIf (cfg.user == "webdav") {
config = lib.mkIf cfg.enable {
users.users = lib.mkIf (cfg.user == "webdav") {
webdav = {
description = "WebDAV daemon user";
group = cfg.group;
@ -83,7 +81,7 @@ in
};
};
users.groups = mkIf (cfg.group == "webdav") {
users.groups = lib.mkIf (cfg.group == "webdav") {
webdav.gid = config.ids.gids.webdav;
};
@ -96,10 +94,10 @@ in
Restart = "on-failure";
User = cfg.user;
Group = cfg.group;
EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
};
};
};
meta.maintainers = with maintainers; [ pmy ];
meta.maintainers = with lib.maintainers; [ pmy ];
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.xtreemfs;
@ -29,13 +26,13 @@ let
dirConfig = pkgs.writeText "xtreemfs-dir-config.properties" ''
uuid = ${cfg.dir.uuid}
listen.port = ${toString cfg.dir.port}
${optionalString (cfg.dir.address != "") "listen.address = ${cfg.dir.address}"}
${lib.optionalString (cfg.dir.address != "") "listen.address = ${cfg.dir.address}"}
http_port = ${toString cfg.dir.httpPort}
babudb.baseDir = ${home}/dir/database
babudb.logDir = ${home}/dir/db-log
babudb.sync = ${if cfg.dir.replication.enable then "FDATASYNC" else cfg.dir.syncMode}
${optionalString cfg.dir.replication.enable "babudb.plugin.0 = ${dirReplicationConfig}"}
${lib.optionalString cfg.dir.replication.enable "babudb.plugin.0 = ${dirReplicationConfig}"}
${cfg.dir.extraConfig}
'';
@ -51,13 +48,13 @@ let
mrcConfig = pkgs.writeText "xtreemfs-mrc-config.properties" ''
uuid = ${cfg.mrc.uuid}
listen.port = ${toString cfg.mrc.port}
${optionalString (cfg.mrc.address != "") "listen.address = ${cfg.mrc.address}"}
${lib.optionalString (cfg.mrc.address != "") "listen.address = ${cfg.mrc.address}"}
http_port = ${toString cfg.mrc.httpPort}
babudb.baseDir = ${home}/mrc/database
babudb.logDir = ${home}/mrc/db-log
babudb.sync = ${if cfg.mrc.replication.enable then "FDATASYNC" else cfg.mrc.syncMode}
${optionalString cfg.mrc.replication.enable "babudb.plugin.0 = ${mrcReplicationConfig}"}
${lib.optionalString cfg.mrc.replication.enable "babudb.plugin.0 = ${mrcReplicationConfig}"}
${cfg.mrc.extraConfig}
'';
@ -65,14 +62,14 @@ let
osdConfig = pkgs.writeText "xtreemfs-osd-config.properties" ''
uuid = ${cfg.osd.uuid}
listen.port = ${toString cfg.osd.port}
${optionalString (cfg.osd.address != "") "listen.address = ${cfg.osd.address}"}
${lib.optionalString (cfg.osd.address != "") "listen.address = ${cfg.osd.address}"}
http_port = ${toString cfg.osd.httpPort}
object_dir = ${home}/osd/
${cfg.osd.extraConfig}
'';
optionalDir = optionals cfg.dir.enable ["xtreemfs-dir.service"];
optionalDir = lib.optionals cfg.dir.enable ["xtreemfs-dir.service"];
systemdOptionalDependencies = {
after = [ "network.target" ] ++ optionalDir;
@ -89,10 +86,10 @@ in
services.xtreemfs = {
enable = mkEnableOption "XtreemFS";
enable = lib.mkEnableOption "XtreemFS";
homeDir = mkOption {
type = types.path;
homeDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/xtreemfs";
description = ''
XtreemFS home dir for the xtreemfs user.
@ -100,32 +97,32 @@ in
};
dir = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable XtreemFS DIR service.
'';
};
uuid = mkOption {
uuid = lib.mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e40";
type = types.str;
type = lib.types.str;
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `util-linux` package.
'';
};
port = mkOption {
port = lib.mkOption {
default = 32638;
type = types.port;
type = lib.types.port;
description = ''
The port to listen on for incoming connections (TCP).
'';
};
address = mkOption {
type = types.str;
address = lib.mkOption {
type = lib.types.str;
example = "127.0.0.1";
default = "";
description = ''
@ -133,16 +130,16 @@ in
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
httpPort = lib.mkOption {
default = 30638;
type = types.port;
type = lib.types.port;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
syncMode = mkOption {
type = types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ];
syncMode = lib.mkOption {
type = lib.types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ];
default = "FSYNC";
example = "FDATASYNC";
description = ''
@ -160,8 +157,8 @@ in
(If xtreemfs.dir.replication.enable is true then FDATASYNC is forced)
'';
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
example = ''
# specify whether SSL is required
@ -180,9 +177,9 @@ in
'';
};
replication = {
enable = mkEnableOption "XtreemFS DIR replication plugin";
extraConfig = mkOption {
type = types.lines;
enable = lib.mkEnableOption "XtreemFS DIR replication plugin";
extraConfig = lib.mkOption {
type = lib.types.lines;
example = ''
# participants of the replication including this replica
babudb.repl.participant.0 = 192.168.0.10
@ -225,50 +222,50 @@ in
};
mrc = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable XtreemFS MRC service.
'';
};
uuid = mkOption {
uuid = lib.mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e41";
type = types.str;
type = lib.types.str;
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `util-linux` package.
'';
};
port = mkOption {
port = lib.mkOption {
default = 32636;
type = types.port;
type = lib.types.port;
description = ''
The port to listen on for incoming connections (TCP).
'';
};
address = mkOption {
address = lib.mkOption {
example = "127.0.0.1";
type = types.str;
type = lib.types.str;
default = "";
description = ''
If specified, it defines the interface to listen on. If not
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
httpPort = lib.mkOption {
default = 30636;
type = types.port;
type = lib.types.port;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
syncMode = mkOption {
syncMode = lib.mkOption {
default = "FSYNC";
type = types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ];
type = lib.types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ];
example = "FDATASYNC";
description = ''
The sync mode influences how operations are committed to the disk
@ -285,8 +282,8 @@ in
(If xtreemfs.mrc.replication.enable is true then FDATASYNC is forced)
'';
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
example = ''
osd_check_interval = 300
no_atime = true
@ -323,9 +320,9 @@ in
'';
};
replication = {
enable = mkEnableOption "XtreemFS MRC replication plugin";
extraConfig = mkOption {
type = types.lines;
enable = lib.mkEnableOption "XtreemFS MRC replication plugin";
extraConfig = lib.mkOption {
type = lib.types.lines;
example = ''
# participants of the replication including this replica
babudb.repl.participant.0 = 192.168.0.10
@ -368,49 +365,49 @@ in
};
osd = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable XtreemFS OSD service.
'';
};
uuid = mkOption {
uuid = lib.mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e42";
type = types.str;
type = lib.types.str;
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `util-linux` package.
'';
};
port = mkOption {
port = lib.mkOption {
default = 32640;
type = types.port;
type = lib.types.port;
description = ''
The port to listen on for incoming connections (TCP and UDP).
'';
};
address = mkOption {
address = lib.mkOption {
example = "127.0.0.1";
type = types.str;
type = lib.types.str;
default = "";
description = ''
If specified, it defines the interface to listen on. If not
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
httpPort = lib.mkOption {
default = 30640;
type = types.port;
type = lib.types.port;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
example = ''
local_clock_renewal = 0
remote_time_sync = 30000
@ -464,7 +461,7 @@ in
{ gid = config.ids.gids.xtreemfs;
};
systemd.services.xtreemfs-dir = mkIf cfg.dir.enable {
systemd.services.xtreemfs-dir = lib.mkIf cfg.dir.enable {
description = "XtreemFS-DIR Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
@ -474,7 +471,7 @@ in
};
};
systemd.services.xtreemfs-mrc = mkIf cfg.mrc.enable ({
systemd.services.xtreemfs-mrc = lib.mkIf cfg.mrc.enable ({
description = "XtreemFS-MRC Server";
serviceConfig = {
User = "xtreemfs";
@ -482,7 +479,7 @@ in
};
} // systemdOptionalDependencies);
systemd.services.xtreemfs-osd = mkIf cfg.osd.enable ({
systemd.services.xtreemfs-osd = lib.mkIf cfg.osd.enable ({
description = "XtreemFS-OSD Server";
serviceConfig = {
User = "xtreemfs";

View File

@ -1,7 +1,4 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.yandex-disk;
@ -20,47 +17,47 @@ in
services.yandex-disk = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable Yandex-disk client. See https://disk.yandex.ru/
'';
};
username = mkOption {
username = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = ''
Your yandex.com login name.
'';
};
password = mkOption {
password = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = ''
Your yandex.com password. Warning: it will be world-readable in /nix/store.
'';
};
user = mkOption {
user = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The user the yandex-disk daemon should run as.
'';
};
directory = mkOption {
type = types.path;
directory = lib.mkOption {
type = lib.types.path;
default = "/home/Yandex.Disk";
description = "The directory to use for Yandex.Disk storage";
};
excludes = mkOption {
excludes = lib.mkOption {
default = "";
type = types.commas;
type = lib.types.commas;
example = "data,backup";
description = ''
Comma-separated list of directories which are excluded from synchronization.
@ -74,9 +71,9 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.users = mkIf (cfg.user == null) [ {
users.users = lib.mkIf (cfg.user == null) [ {
name = u;
uid = config.ids.uids.yandexdisk;
group = "nogroup";

View File

@ -1,21 +1,20 @@
{ config, lib, pkgs, ... }:
with lib;
let
pkg = pkgs._3proxy;
cfg = config.services._3proxy;
optionalList = list: if list == [ ] then "*" else concatMapStringsSep "," toString list;
optionalList = list: if list == [ ] then "*" else lib.concatMapStringsSep "," toString list;
in {
options.services._3proxy = {
enable = mkEnableOption "3proxy";
confFile = mkOption {
type = types.path;
enable = lib.mkEnableOption "3proxy";
confFile = lib.mkOption {
type = lib.types.path;
example = "/var/lib/3proxy/3proxy.conf";
description = ''
Ignore all other 3proxy options and load configuration from this file.
'';
};
usersFile = mkOption {
type = types.nullOr types.path;
usersFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = "/var/lib/3proxy/3proxy.passwd";
description = ''
@ -40,11 +39,11 @@ in {
Consult [documentation](https://github.com/z3APA3A/3proxy/wiki/How-To-%28incomplete%29#USERS) for more information.
'';
};
services = mkOption {
type = types.listOf (types.submodule {
services = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
type = mkOption {
type = types.enum [
type = lib.mkOption {
type = lib.types.enum [
"proxy"
"socks"
"pop3p"
@ -68,32 +67,32 @@ in {
- `"udppm"`: UDP portmapper.
'';
};
bindAddress = mkOption {
type = types.str;
bindAddress = lib.mkOption {
type = lib.types.str;
default = "[::]";
example = "127.0.0.1";
description = ''
Address used for service.
'';
};
bindPort = mkOption {
type = types.nullOr types.int;
bindPort = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 3128;
description = ''
Override default port used for service.
'';
};
maxConnections = mkOption {
type = types.int;
maxConnections = lib.mkOption {
type = lib.types.int;
default = 100;
example = 1000;
description = ''
Maximum number of simulationeous connections to this service.
'';
};
auth = mkOption {
type = types.listOf (types.enum [ "none" "iponly" "strong" ]);
auth = lib.mkOption {
type = lib.types.listOf (lib.types.enum [ "none" "iponly" "strong" ]);
example = [ "iponly" "strong" ];
description = ''
Authentication type. The following values are valid:
@ -122,11 +121,11 @@ in {
In this example strong username authentication is not required to access 192.168.0.0/16.
'';
};
acl = mkOption {
type = types.listOf (types.submodule {
acl = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
rule = mkOption {
type = types.enum [ "allow" "deny" ];
rule = lib.mkOption {
type = lib.types.enum [ "allow" "deny" ];
example = "allow";
description = ''
ACL rule. The following values are valid:
@ -135,24 +134,24 @@ in {
- `"deny"`: connections not allowed.
'';
};
users = mkOption {
type = types.listOf types.str;
users = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "user1" "user2" "user3" ];
description = ''
List of users, use empty list for any.
'';
};
sources = mkOption {
type = types.listOf types.str;
sources = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "127.0.0.1" "192.168.1.0/24" ];
description = ''
List of source IP range, use empty list for any.
'';
};
targets = mkOption {
type = types.listOf types.str;
targets = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "127.0.0.1" "192.168.1.0/24" ];
description = ''
@ -162,8 +161,8 @@ in {
Hostname is only checked if hostname presents in request.
'';
};
targetPorts = mkOption {
type = types.listOf types.int;
targetPorts = lib.mkOption {
type = lib.types.listOf lib.types.int;
default = [ ];
example = [ 80 443 ];
description = ''
@ -173,7 +172,7 @@ in {
};
});
default = [ ];
example = literalExpression ''
example = lib.literalExpression ''
[
{
rule = "allow";
@ -192,8 +191,8 @@ in {
Use this option to limit user access to resources.
'';
};
extraArguments = mkOption {
type = types.nullOr types.str;
extraArguments = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "-46";
description = ''
@ -201,8 +200,8 @@ in {
Consult "Options" section in [documentation](https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg) for available arguments.
'';
};
extraConfig = mkOption {
type = types.nullOr types.lines;
extraConfig = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
description = ''
Extra configuration for service. Use this to configure things like bandwidth limiter or ACL-based redirection.
@ -212,7 +211,7 @@ in {
};
});
default = [ ];
example = literalExpression ''
example = lib.literalExpression ''
[
{
type = "proxy";
@ -238,15 +237,15 @@ in {
Use this option to define 3proxy services.
'';
};
denyPrivate = mkOption {
type = types.bool;
denyPrivate = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to deny access to private IP ranges including loopback.
'';
};
privateRanges = mkOption {
type = types.listOf types.str;
privateRanges = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"0.0.0.0/8"
"127.0.0.0/8"
@ -262,11 +261,11 @@ in {
What IP ranges to deny access when denyPrivate is set tu true.
'';
};
resolution = mkOption {
type = types.submodule {
resolution = lib.mkOption {
type = lib.types.submodule {
options = {
nserver = mkOption {
type = types.listOf types.str;
nserver = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "127.0.0.53" "192.168.1.3:5353/tcp" ];
description = ''
@ -276,20 +275,20 @@ in {
default system name resolution functions are used.
'';
};
nscache = mkOption {
type = types.int;
nscache = lib.mkOption {
type = lib.types.int;
default = 65535;
description = "Set name cache size for IPv4.";
};
nscache6 = mkOption {
type = types.int;
nscache6 = lib.mkOption {
type = lib.types.int;
default = 65535;
description = "Set name cache size for IPv6.";
};
nsrecord = mkOption {
type = types.attrsOf types.str;
nsrecord = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
"files.local" = "192.168.1.12";
"site.local" = "192.168.1.43";
@ -304,8 +303,8 @@ in {
Use this option to configure name resolution and DNS caching.
'';
};
extraConfig = mkOption {
type = types.nullOr types.lines;
extraConfig = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
description = ''
Extra configuration, appended to the 3proxy configuration file.
@ -314,33 +313,33 @@ in {
};
};
config = mkIf cfg.enable {
services._3proxy.confFile = mkDefault (pkgs.writeText "3proxy.conf" ''
config = lib.mkIf cfg.enable {
services._3proxy.confFile = lib.mkDefault (pkgs.writeText "3proxy.conf" ''
# log to stdout
log
${concatMapStringsSep "\n" (x: "nserver " + x) cfg.resolution.nserver}
${lib.concatMapStringsSep "\n" (x: "nserver " + x) cfg.resolution.nserver}
nscache ${toString cfg.resolution.nscache}
nscache6 ${toString cfg.resolution.nscache6}
${concatMapStringsSep "\n" (x: "nsrecord " + x)
(mapAttrsToList (name: value: "${name} ${value}")
${lib.concatMapStringsSep "\n" (x: "nsrecord " + x)
(lib.mapAttrsToList (name: value: "${name} ${value}")
cfg.resolution.nsrecord)}
${optionalString (cfg.usersFile != null)
${lib.optionalString (cfg.usersFile != null)
''users $"${cfg.usersFile}"''
}
${concatMapStringsSep "\n" (service: ''
auth ${concatStringsSep " " service.auth}
${lib.concatMapStringsSep "\n" (service: ''
auth ${lib.concatStringsSep " " service.auth}
${optionalString (cfg.denyPrivate)
${lib.optionalString (cfg.denyPrivate)
"deny * * ${optionalList cfg.privateRanges}"}
${concatMapStringsSep "\n" (acl:
${lib.concatMapStringsSep "\n" (acl:
"${acl.rule} ${
concatMapStringsSep " " optionalList [
lib.concatMapStringsSep " " optionalList [
acl.users
acl.sources
acl.targets
@ -350,18 +349,18 @@ in {
maxconn ${toString service.maxConnections}
${optionalString (service.extraConfig != null) service.extraConfig}
${lib.optionalString (service.extraConfig != null) service.extraConfig}
${service.type} -i${toString service.bindAddress} ${
optionalString (service.bindPort != null)
lib.optionalString (service.bindPort != null)
"-p${toString service.bindPort}"
} ${
optionalString (service.extraArguments != null) service.extraArguments
lib.optionalString (service.extraArguments != null) service.extraArguments
}
flush
'') cfg.services}
${optionalString (cfg.extraConfig != null) cfg.extraConfig}
${lib.optionalString (cfg.extraConfig != null) cfg.extraConfig}
'');
systemd.services."3proxy" = {
description = "Tiny free proxy server";
@ -377,5 +376,5 @@ in {
};
};
meta.maintainers = with maintainers; [ misuzu ];
meta.maintainers = with lib.maintainers; [ misuzu ];
}

View File

@ -1,12 +1,9 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.adguardhome;
settingsFormat = pkgs.formats.yaml { };
args = concatStringsSep " " ([
args = lib.concatStringsSep " " ([
"--no-check-update"
"--pidfile /run/AdGuardHome/AdGuardHome.pid"
"--work-dir /var/lib/AdGuardHome/"
@ -28,19 +25,19 @@ let
checkPhase = "${cfg.package}/bin/adguardhome -c $out --check-config";
});
in {
options.services.adguardhome = with types; {
enable = mkEnableOption "AdGuard Home network-wide ad blocker";
options.services.adguardhome = with lib.types; {
enable = lib.mkEnableOption "AdGuard Home network-wide ad blocker";
package = mkOption {
package = lib.mkOption {
type = package;
default = pkgs.adguardhome;
defaultText = literalExpression "pkgs.adguardhome";
defaultText = lib.literalExpression "pkgs.adguardhome";
description = ''
The package that runs adguardhome.
'';
};
openFirewall = mkOption {
openFirewall = lib.mkOption {
default = false;
type = bool;
description = ''
@ -49,9 +46,9 @@ in {
'';
};
allowDHCP = mkOption {
allowDHCP = lib.mkOption {
default = settings.dhcp.enabled or false;
defaultText = literalExpression "config.services.adguardhome.settings.dhcp.enabled or false";
defaultText = lib.literalExpression "config.services.adguardhome.settings.dhcp.enabled or false";
type = bool;
description = ''
Allows AdGuard Home to open raw sockets (`CAP_NET_RAW`), which is
@ -63,7 +60,7 @@ in {
'';
};
mutableSettings = mkOption {
mutableSettings = lib.mkOption {
default = true;
type = bool;
description = ''
@ -72,7 +69,7 @@ in {
'';
};
host = mkOption {
host = lib.mkOption {
default = "0.0.0.0";
type = str;
description = ''
@ -80,7 +77,7 @@ in {
'';
};
port = mkOption {
port = lib.mkOption {
default = 3000;
type = port;
description = ''
@ -88,14 +85,14 @@ in {
'';
};
settings = mkOption {
settings = lib.mkOption {
default = null;
type = nullOr (submodule {
freeformType = settingsFormat.type;
options = {
schema_version = mkOption {
schema_version = lib.mkOption {
default = cfg.package.schema_version;
defaultText = literalExpression "cfg.package.schema_version";
defaultText = lib.literalExpression "cfg.package.schema_version";
type = int;
description = ''
Schema version for the configuration.
@ -121,7 +118,7 @@ in {
'';
};
extraArgs = mkOption {
extraArgs = lib.mkOption {
default = [ ];
type = listOf str;
description = ''
@ -130,27 +127,27 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.settings != null
-> !(hasAttrByPath [ "bind_host" ] cfg.settings);
-> !(lib.hasAttrByPath [ "bind_host" ] cfg.settings);
message = "AdGuard option `settings.bind_host' has been superseded by `services.adguardhome.host'";
}
{
assertion = cfg.settings != null
-> !(hasAttrByPath [ "bind_port" ] cfg.settings);
-> !(lib.hasAttrByPath [ "bind_port" ] cfg.settings);
message = "AdGuard option `settings.bind_port' has been superseded by `services.adguardhome.port'";
}
{
assertion = settings != null -> cfg.mutableSettings
|| hasAttrByPath [ "dns" "bootstrap_dns" ] settings;
|| lib.hasAttrByPath [ "dns" "bootstrap_dns" ] settings;
message = "AdGuard setting dns.bootstrap_dns needs to be configured for a minimal working configuration";
}
{
assertion = settings != null -> cfg.mutableSettings
|| hasAttrByPath [ "dns" "bootstrap_dns" ] settings
&& isList settings.dns.bootstrap_dns;
|| lib.hasAttrByPath [ "dns" "bootstrap_dns" ] settings
&& lib.isList settings.dns.bootstrap_dns;
message = "AdGuard setting dns.bootstrap_dns needs to be a list";
}
];
@ -164,7 +161,7 @@ in {
StartLimitBurst = 10;
};
preStart = optionalString (settings != null) ''
preStart = lib.optionalString (settings != null) ''
if [ -e "$STATE_DIRECTORY/AdGuardHome.yaml" ] \
&& [ "${toString cfg.mutableSettings}" = "1" ]; then
# First run a schema_version update on the existing configuration
@ -185,7 +182,7 @@ in {
DynamicUser = true;
ExecStart = "${lib.getExe cfg.package} ${args}";
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]
++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ];
++ lib.optionals cfg.allowDHCP [ "CAP_NET_RAW" ];
Restart = "always";
RestartSec = 10;
RuntimeDirectory = "AdGuardHome";
@ -193,6 +190,6 @@ in {
};
};
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
};
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.alice-lg;
settingsFormat = pkgs.formats.ini { };
@ -9,17 +6,17 @@ in
{
options = {
services.alice-lg = {
enable = mkEnableOption "Alice Looking Glass";
enable = lib.mkEnableOption "Alice Looking Glass";
package = mkPackageOption pkgs "alice-lg" { };
package = lib.mkPackageOption pkgs "alice-lg" { };
settings = mkOption {
settings = lib.mkOption {
type = settingsFormat.type;
default = { };
description = ''
alice-lg configuration, for configuration options see the example on [github](https://github.com/alice-lg/alice-lg/blob/main/etc/alice-lg/alice.example.conf)
'';
example = literalExpression ''
example = lib.literalExpression ''
{
server = {
# configures the built-in webserver and provides global application settings

View File

@ -1,7 +1,4 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.amule;
opt = options.services.amule;
@ -16,18 +13,18 @@ in
services.amule = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to run the AMule daemon. You need to manually run "amuled --ec-config" to configure the service for the first time.
'';
};
dataDir = mkOption {
type = types.str;
dataDir = lib.mkOption {
type = lib.types.str;
default = "/home/${user}/";
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
"/home/''${config.${opt.user}}/"
'';
description = ''
@ -35,8 +32,8 @@ in
'';
};
user = mkOption {
type = types.nullOr types.str;
user = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The user the AMule daemon should run as.
@ -50,16 +47,16 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.users = mkIf (cfg.user == null) [
users.users = lib.mkIf (cfg.user == null) [
{ name = "amule";
description = "AMule daemon";
group = "amule";
uid = config.ids.uids.amule;
} ];
users.groups = mkIf (cfg.user == null) [
users.groups = lib.mkIf (cfg.user == null) [
{ name = "amule";
gid = config.ids.gids.amule;
} ];

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.asterisk;
@ -13,7 +10,7 @@ let
logdir = "/var/log/asterisk";
# Add filecontents from files of useTheseDefaultConfFiles to confFiles, do not override
defaultConfFiles = subtractLists (attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles;
defaultConfFiles = lib.subtractLists (lib.attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles;
allConfFiles = {
# Default asterisk.conf file
"asterisk.conf".text = ''
@ -48,25 +45,25 @@ let
syslog.local0 => notice,warning,error
'';
} //
mapAttrs (name: text: { inherit text; }) cfg.confFiles //
listToAttrs (map (x: nameValuePair x { source = cfg.package + "/etc/asterisk/" + x; }) defaultConfFiles);
lib.mapAttrs (name: text: { inherit text; }) cfg.confFiles //
lib.listToAttrs (map (x: lib.nameValuePair x { source = cfg.package + "/etc/asterisk/" + x; }) defaultConfFiles);
in
{
options = {
services.asterisk = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the Asterisk PBX server.
'';
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
example = ''
[options]
verbose=3
@ -78,10 +75,10 @@ in
'';
};
confFiles = mkOption {
confFiles = lib.mkOption {
default = {};
type = types.attrsOf types.str;
example = literalExpression
type = lib.types.attrsOf lib.types.str;
example = lib.literalExpression
''
{
"extensions.conf" = '''
@ -144,9 +141,9 @@ in
'';
};
useTheseDefaultConfFiles = mkOption {
useTheseDefaultConfFiles = lib.mkOption {
default = [ "ari.conf" "acl.conf" "agents.conf" "amd.conf" "calendar.conf" "cdr.conf" "cdr_syslog.conf" "cdr_custom.conf" "cel.conf" "cel_custom.conf" "cli_aliases.conf" "confbridge.conf" "dundi.conf" "features.conf" "hep.conf" "iax.conf" "pjsip.conf" "pjsip_wizard.conf" "phone.conf" "phoneprov.conf" "queues.conf" "res_config_sqlite3.conf" "res_parking.conf" "statsd.conf" "udptl.conf" "unistim.conf" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
example = [ "sip.conf" "dundi.conf" ];
description = ''Sets these config files to the default content. The default value for
this option contains all necesscary files to avoid errors at startup.
@ -154,24 +151,24 @@ in
'';
};
extraArguments = mkOption {
extraArguments = lib.mkOption {
default = [];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
example =
[ "-vvvddd" "-e" "1024" ];
description = ''
Additional command line arguments to pass to Asterisk.
'';
};
package = mkPackageOption pkgs "asterisk" { };
package = lib.mkPackageOption pkgs "asterisk" { };
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc = mapAttrs' (name: value:
nameValuePair "asterisk/${name}" value
environment.etc = lib.mapAttrs' (name: value:
lib.nameValuePair "asterisk/${name}" value
) allConfFiles;
users.users.asterisk =
@ -214,7 +211,7 @@ in
ExecStart =
let
# FIXME: This doesn't account for arguments with spaces
argString = concatStringsSep " " cfg.extraArguments;
argString = lib.concatStringsSep " " cfg.extraArguments;
in
"${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
ExecReload = ''${cfg.package}/bin/asterisk -x "core reload"

View File

@ -1,9 +1,5 @@
# NixOS module for atftpd TFTP server
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.atftpd;
@ -16,19 +12,19 @@ in
services.atftpd = {
enable = mkOption {
enable = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Whether to enable the atftpd TFTP server. By default, the server
binds to address 0.0.0.0.
'';
};
extraOptions = mkOption {
extraOptions = lib.mkOption {
default = [];
type = types.listOf types.str;
example = literalExpression ''
type = lib.types.listOf lib.types.str;
example = lib.literalExpression ''
[ "--bind-address 192.168.9.1"
"--verbose=7"
]
@ -38,9 +34,9 @@ in
'';
};
root = mkOption {
root = lib.mkOption {
default = "/srv/tftp";
type = types.path;
type = lib.types.path;
description = ''
Document root directory for the atftpd.
'';
@ -50,7 +46,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.atftpd = {
description = "TFTP Server";

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.autossh;
@ -16,21 +13,21 @@ in
services.autossh = {
sessions = mkOption {
type = types.listOf (types.submodule {
sessions = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
name = mkOption {
type = types.str;
name = lib.mkOption {
type = lib.types.str;
example = "socks-peer";
description = "Name of the local AutoSSH session";
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
example = "bill";
description = "Name of the user the AutoSSH session should run as";
};
monitoringPort = mkOption {
type = types.int;
monitoringPort = lib.mkOption {
type = lib.types.int;
default = 0;
example = 20000;
description = ''
@ -39,8 +36,8 @@ in
style monitoring
'';
};
extraArguments = mkOption {
type = types.separatedString " ";
extraArguments = lib.mkOption {
type = lib.types.separatedString " ";
example = "-N -D4343 bill@socks.example.net";
description = ''
Arguments to be passed to AutoSSH and retransmitted to SSH
@ -75,7 +72,7 @@ in
###### implementation
config = mkIf (cfg.sessions != []) {
config = lib.mkIf (cfg.sessions != []) {
systemd.services =

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.avahi;
@ -13,15 +10,15 @@ let
# a host name from DHCP. In that case, let Avahi take whatever the
# current host name is; setting `host-name' to the empty string in
# `avahi-daemon.conf' would be invalid.
optionalString (hostName != "") "host-name=${hostName}"}
browse-domains=${concatStringsSep ", " browseDomains}
lib.optionalString (hostName != "") "host-name=${hostName}"}
browse-domains=${lib.concatStringsSep ", " browseDomains}
use-ipv4=${yesNo ipv4}
use-ipv6=${yesNo ipv6}
${optionalString (allowInterfaces!=null) "allow-interfaces=${concatStringsSep "," allowInterfaces}"}
${optionalString (denyInterfaces!=null) "deny-interfaces=${concatStringsSep "," denyInterfaces}"}
${optionalString (domainName!=null) "domain-name=${domainName}"}
${lib.optionalString (allowInterfaces!=null) "allow-interfaces=${lib.concatStringsSep "," allowInterfaces}"}
${lib.optionalString (denyInterfaces!=null) "deny-interfaces=${lib.concatStringsSep "," denyInterfaces}"}
${lib.optionalString (domainName!=null) "domain-name=${domainName}"}
allow-point-to-point=${yesNo allowPointToPoint}
${optionalString (cacheEntriesMax!=null) "cache-entries-max=${toString cacheEntriesMax}"}
${lib.optionalString (cacheEntriesMax!=null) "cache-entries-max=${toString cacheEntriesMax}"}
[wide-area]
enable-wide-area=${yesNo wideArea}
@ -46,8 +43,8 @@ in
];
options.services.avahi = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to run the Avahi daemon, which allows Avahi clients
@ -57,28 +54,28 @@ in
'';
};
package = mkPackageOption pkgs "avahi" { };
package = lib.mkPackageOption pkgs "avahi" { };
hostName = mkOption {
type = types.str;
hostName = lib.mkOption {
type = lib.types.str;
default = config.networking.hostName;
defaultText = literalExpression "config.networking.hostName";
defaultText = lib.literalExpression "config.networking.hostName";
description = ''
Host name advertised on the LAN. If not set, avahi will use the value
of {option}`config.networking.hostName`.
'';
};
domainName = mkOption {
type = types.str;
domainName = lib.mkOption {
type = lib.types.str;
default = "local";
description = ''
Domain name for all advertisements.
'';
};
browseDomains = mkOption {
type = types.listOf types.str;
browseDomains = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "0pointer.de" "zeroconf.org" ];
description = ''
@ -86,20 +83,20 @@ in
'';
};
ipv4 = mkOption {
type = types.bool;
ipv4 = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to use IPv4.";
};
ipv6 = mkOption {
type = types.bool;
ipv6 = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to use IPv6.";
};
allowInterfaces = mkOption {
type = types.nullOr (types.listOf types.str);
allowInterfaces = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
description = ''
List of network interfaces that should be used by the {command}`avahi-daemon`.
@ -108,8 +105,8 @@ in
'';
};
denyInterfaces = mkOption {
type = types.nullOr (types.listOf types.str);
denyInterfaces = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
description = ''
List of network interfaces that should be ignored by the
@ -119,8 +116,8 @@ in
'';
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to open the firewall for UDP port 5353.
@ -128,8 +125,8 @@ in
'';
};
allowPointToPoint = mkOption {
type = types.bool;
allowPointToPoint = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large
@ -138,22 +135,22 @@ in
'';
};
wideArea = mkOption {
type = types.bool;
wideArea = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to enable wide-area service discovery.";
};
reflector = mkOption {
type = types.bool;
reflector = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Reflect incoming mDNS requests to all allowed network interfaces.";
};
extraServiceFiles = mkOption {
type = with types; attrsOf (either str path);
extraServiceFiles = lib.mkOption {
type = with lib.types; attrsOf (either str path);
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
ssh = "''${pkgs.avahi}/etc/avahi/services/ssh.service";
smb = '''
@ -176,26 +173,26 @@ in
};
publish = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to allow publishing in general.";
};
userServices = mkOption {
type = types.bool;
userServices = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to publish user services. Will set `addresses=true`.";
};
addresses = mkOption {
type = types.bool;
addresses = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to register mDNS address records for all local IP addresses.";
};
hinfo = mkOption {
type = types.bool;
hinfo = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to register a mDNS HINFO record which contains information about the
@ -203,23 +200,23 @@ in
'';
};
workstation = mkOption {
type = types.bool;
workstation = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to register a service of type "_workstation._tcp" on the local LAN.
'';
};
domain = mkOption {
type = types.bool;
domain = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to announce the locally used domain name for browsing by other hosts.";
};
};
nssmdns4 = mkOption {
type = types.bool;
nssmdns4 = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the mDNS NSS (Name Service Switch) plug-in for IPv4.
@ -228,8 +225,8 @@ in
'';
};
nssmdns6 = mkOption {
type = types.bool;
nssmdns6 = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the mDNS NSS (Name Service Switch) plug-in for IPv6.
@ -243,8 +240,8 @@ in
'';
};
cacheEntriesMax = mkOption {
type = types.nullOr types.int;
cacheEntriesMax = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = ''
Number of resource records to be cached per interface. Use 0 to
@ -252,8 +249,8 @@ in
'';
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra config to append to avahi-daemon.conf.
@ -261,7 +258,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.users.avahi = {
description = "avahi-daemon privilege separation user";
home = "/var/empty";
@ -271,7 +268,7 @@ in
users.groups.avahi = { };
system.nssModules = optional (cfg.nssmdns4 || cfg.nssmdns6) pkgs.nssmdns;
system.nssModules = lib.optional (cfg.nssmdns4 || cfg.nssmdns6) pkgs.nssmdns;
system.nssDatabases.hosts = let
mdns = if (cfg.nssmdns4 && cfg.nssmdns6) then
"mdns"
@ -281,17 +278,17 @@ in
"mdns4"
else
"";
in optionals (cfg.nssmdns4 || cfg.nssmdns6) (mkMerge [
(mkBefore [ "${mdns}_minimal [NOTFOUND=return]" ]) # before resolve
(mkAfter [ "${mdns}" ]) # after dns
in lib.optionals (cfg.nssmdns4 || cfg.nssmdns6) (lib.mkMerge [
(lib.mkBefore [ "${mdns}_minimal [NOTFOUND=return]" ]) # before resolve
(lib.mkAfter [ "${mdns}" ]) # after dns
]);
environment.systemPackages = [ cfg.package ];
environment.etc = (mapAttrs'
(n: v: nameValuePair
environment.etc = (lib.mapAttrs'
(n: v: lib.nameValuePair
"avahi/services/${n}.service"
{ ${if types.path.check v then "source" else "text"} = v; }
{ ${if lib.types.path.check v then "source" else "text"} = v; }
)
cfg.extraServiceFiles);
@ -326,6 +323,6 @@ in
services.dbus.enable = true;
services.dbus.packages = [ cfg.package ];
networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ 5353 ];
networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [ 5353 ];
};
}

View File

@ -1,20 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.babeld;
conditionalBoolToString = value: if (isBool value) then (boolToString value) else (toString value);
conditionalBoolToString = value: if (lib.isBool value) then (lib.boolToString value) else (toString value);
paramsString = params:
concatMapStringsSep " " (name: "${name} ${conditionalBoolToString (getAttr name params)}")
(attrNames params);
lib.concatMapStringsSep " " (name: "${name} ${conditionalBoolToString (lib.getAttr name params)}")
(lib.attrNames params);
interfaceConfig = name:
let
interface = getAttr name cfg.interfaces;
interface = lib.getAttr name cfg.interfaces;
in
"interface ${name} ${paramsString interface}\n";
@ -22,17 +19,17 @@ let
''
skip-kernel-setup true
''
+ (optionalString (cfg.interfaceDefaults != null) ''
+ (lib.optionalString (cfg.interfaceDefaults != null) ''
default ${paramsString cfg.interfaceDefaults}
'')
+ (concatMapStrings interfaceConfig (attrNames cfg.interfaces))
+ (lib.concatMapStrings interfaceConfig (lib.attrNames cfg.interfaces))
+ extraConfig);
in
{
meta.maintainers = with maintainers; [ hexa ];
meta.maintainers = with lib.maintainers; [ hexa ];
###### interface
@ -40,15 +37,15 @@ in
services.babeld = {
enable = mkEnableOption "the babeld network routing daemon";
enable = lib.mkEnableOption "the babeld network routing daemon";
interfaceDefaults = mkOption {
interfaceDefaults = lib.mkOption {
default = null;
description = ''
A set describing default parameters for babeld interfaces.
See {manpage}`babeld(8)` for options.
'';
type = types.nullOr (types.attrsOf types.unspecified);
type = lib.types.nullOr (lib.types.attrsOf lib.types.unspecified);
example =
{
type = "tunnel";
@ -56,13 +53,13 @@ in
};
};
interfaces = mkOption {
interfaces = lib.mkOption {
default = {};
description = ''
A set describing babeld interfaces.
See {manpage}`babeld(8)` for options.
'';
type = types.attrsOf (types.attrsOf types.unspecified);
type = lib.types.attrsOf (lib.types.attrsOf lib.types.unspecified);
example =
{ enp0s2 =
{ type = "wired";
@ -72,9 +69,9 @@ in
};
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Options that will be copied to babeld.conf.
See {manpage}`babeld(8)` for details.
@ -87,7 +84,7 @@ in
###### implementation
config = mkIf config.services.babeld.enable {
config = lib.mkIf config.services.babeld.enable {
boot.kernel.sysctl = {
"net.ipv6.conf.all.forwarding" = 1;

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.bee;
format = pkgs.formats.yaml {};
@ -15,13 +13,13 @@ in {
options = {
services.bee = {
enable = mkEnableOption "Ethereum Swarm Bee";
enable = lib.mkEnableOption "Ethereum Swarm Bee";
package = mkPackageOption pkgs "bee" {
package = lib.mkPackageOption pkgs "bee" {
example = "bee-unstable";
};
settings = mkOption {
settings = lib.mkOption {
type = format.type;
description = ''
Ethereum Swarm Bee configuration. Refer to
@ -30,8 +28,8 @@ in {
'';
};
daemonNiceLevel = mkOption {
type = types.int;
daemonNiceLevel = lib.mkOption {
type = lib.types.int;
default = 0;
description = ''
Daemon process priority for bee.
@ -39,16 +37,16 @@ in {
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "bee";
description = ''
User the bee binary should execute under.
'';
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "bee";
description = ''
Group the bee binary should execute under.
@ -59,14 +57,14 @@ in {
### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{ assertion = (hasAttr "password" cfg.settings) != true;
{ assertion = (lib.hasAttr "password" cfg.settings) != true;
message = ''
`services.bee.settings.password` is insecure. Use `services.bee.settings.password-file` or `systemd.services.bee.serviceConfig.EnvironmentFile` instead.
'';
}
{ assertion = (hasAttr "swap-endpoint" cfg.settings) || (cfg.settings.swap-enable or true == false);
{ assertion = (lib.hasAttr "swap-endpoint" cfg.settings) || (cfg.settings.swap-enable or true == false);
message = ''
In a swap-enabled network a working Ethereum blockchain node is required. You must specify one using `services.bee.settings.swap-endpoint`, or disable `services.bee.settings.swap-enable` = false.
'';
@ -119,7 +117,7 @@ After you finish configuration run 'sudo bee-get-addr'."
'';
};
users.users = optionalAttrs (cfg.user == "bee") {
users.users = lib.optionalAttrs (cfg.user == "bee") {
bee = {
group = cfg.group;
home = cfg.settings.data-dir;
@ -128,7 +126,7 @@ After you finish configuration run 'sudo bee-get-addr'."
};
};
users.groups = optionalAttrs (cfg.group == "bee") {
users.groups = lib.optionalAttrs (cfg.group == "bee") {
bee = {};
};
};

View File

@ -1,62 +1,61 @@
{ config, lib, pkgs, options, ... }:
with lib;
let
cfg = config.services.biboumi;
inherit (config.environment) etc;
rootDir = "/run/biboumi/mnt-root";
stateDir = "/var/lib/biboumi";
settingsFile = pkgs.writeText "biboumi.cfg" (
generators.toKeyValue {
lib.generators.toKeyValue {
mkKeyValue = k: v:
lib.optionalString (v != null) (generators.mkKeyValueDefault {} "=" k v);
lib.optionalString (v != null) (lib.generators.mkKeyValueDefault {} "=" k v);
} cfg.settings);
need_CAP_NET_BIND_SERVICE = cfg.settings.identd_port != 0 && cfg.settings.identd_port < 1024;
in
{
options = {
services.biboumi = {
enable = mkEnableOption "the Biboumi XMPP gateway to IRC";
enable = lib.mkEnableOption "the Biboumi XMPP gateway to IRC";
settings = mkOption {
settings = lib.mkOption {
description = ''
See [biboumi 8.5](https://lab.louiz.org/louiz/biboumi/blob/8.5/doc/biboumi.1.rst)
for documentation.
'';
default = {};
type = types.submodule {
freeformType = with types;
type = lib.types.submodule {
freeformType = with lib.types;
(attrsOf (nullOr (oneOf [str int bool]))) // {
description = "settings option";
};
options.admin = mkOption {
type = with types; listOf str;
options.admin = lib.mkOption {
type = with lib.types; listOf str;
default = [];
example = ["admin@example.org"];
apply = concatStringsSep ":";
apply = lib.concatStringsSep ":";
description = ''
The bare JID of the gateway administrator. This JID will have more
privileges than other standard users, for example some administration
ad-hoc commands will only be available to that JID.
'';
};
options.ca_file = mkOption {
type = types.path;
options.ca_file = lib.mkOption {
type = lib.types.path;
default = "/etc/ssl/certs/ca-certificates.crt";
description = ''
Specifies which file should be used as the list of trusted CA
when negotiating a TLS session.
'';
};
options.db_name = mkOption {
type = with types; either path str;
options.db_name = lib.mkOption {
type = with lib.types; either path str;
default = "${stateDir}/biboumi.sqlite";
description = ''
The name of the database to use.
'';
example = "postgresql://user:secret@localhost";
};
options.hostname = mkOption {
type = types.str;
options.hostname = lib.mkOption {
type = lib.types.str;
example = "biboumi.example.org";
description = ''
The hostname served by the XMPPgateway.
@ -64,24 +63,24 @@ in
as an external component.
'';
};
options.identd_port = mkOption {
type = types.port;
options.identd_port = lib.mkOption {
type = lib.types.port;
default = 113;
example = 0;
description = ''
The TCP port on which to listen for identd queries.
'';
};
options.log_level = mkOption {
type = types.ints.between 0 3;
options.log_level = lib.mkOption {
type = lib.types.ints.between 0 3;
default = 1;
description = ''
Indicate what type of log messages to write in the logs.
0 is debug, 1 is info, 2 is warning, 3 is error.
'';
};
options.password = mkOption {
type = with types; nullOr str;
options.password = lib.mkOption {
type = with lib.types; nullOr str;
description = ''
The password used to authenticate the XMPP component to your XMPP server.
This password must be configured in the XMPP server,
@ -92,8 +91,8 @@ in
if you do not want this password to go into the Nix store.
'';
};
options.persistent_by_default = mkOption {
type = types.bool;
options.persistent_by_default = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether all rooms will be persistent by default:
@ -103,25 +102,25 @@ in
persistent configuration option to false in order to override this.
'';
};
options.policy_directory = mkOption {
type = types.path;
options.policy_directory = lib.mkOption {
type = lib.types.path;
default = "${pkgs.biboumi}/etc/biboumi";
defaultText = literalExpression ''"''${pkgs.biboumi}/etc/biboumi"'';
defaultText = lib.literalExpression ''"''${pkgs.biboumi}/etc/biboumi"'';
description = ''
A directory that should contain the policy files,
used to customize Botans behaviour
when negotiating the TLS connections with the IRC servers.
'';
};
options.port = mkOption {
type = types.port;
options.port = lib.mkOption {
type = lib.types.port;
default = 5347;
description = ''
The TCP port to use to connect to the local XMPP component.
'';
};
options.realname_customization = mkOption {
type = types.bool;
options.realname_customization = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether the users will be able to use
@ -129,8 +128,8 @@ in
their realname and username.
'';
};
options.realname_from_jid = mkOption {
type = types.bool;
options.realname_from_jid = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether the realname and username of each biboumi
@ -139,8 +138,8 @@ in
they used to connect to the IRC server.
'';
};
options.xmpp_server_ip = mkOption {
type = types.str;
options.xmpp_server_ip = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
The IP address to connect to the XMPP server on.
@ -152,8 +151,8 @@ in
};
};
credentialsFile = mkOption {
type = types.path;
credentialsFile = lib.mkOption {
type = lib.types.path;
description = ''
Path to a configuration file to be merged with the settings.
Beware not to surround "=" with spaces when setting biboumi's options in this file.
@ -165,12 +164,12 @@ in
example = "/run/keys/biboumi.cfg";
};
openFirewall = mkEnableOption "opening of the identd port in the firewall";
openFirewall = lib.mkEnableOption "opening of the identd port in the firewall";
};
};
config = mkIf cfg.enable {
networking.firewall = mkIf (cfg.openFirewall && cfg.settings.identd_port != 0)
config = lib.mkIf cfg.enable {
networking.firewall = lib.mkIf (cfg.openFirewall && cfg.settings.identd_port != 0)
{ allowedTCPPorts = [ cfg.settings.identd_port ]; };
systemd.services.biboumi = {
@ -202,7 +201,7 @@ in
RootDirectory = rootDir;
RootDirectoryStartOnly = true;
InaccessiblePaths = [ "-+${rootDir}" ];
RuntimeDirectory = [ "biboumi" (removePrefix "/run/" rootDir) ];
RuntimeDirectory = [ "biboumi" (lib.removePrefix "/run/" rootDir) ];
RuntimeDirectoryMode = "700";
StateDirectory = "biboumi";
StateDirectoryMode = "700";
@ -221,8 +220,8 @@ in
];
# The following options are only for optimizing:
# systemd-analyze security biboumi
AmbientCapabilities = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
CapabilityBoundingSet = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
AmbientCapabilities = [ (lib.optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
CapabilityBoundingSet = [ (lib.optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
# ProtectClock= adds DeviceAllow=char-rtc r
DeviceAllow = "";
LockPersonality = true;
@ -230,7 +229,7 @@ in
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateNetwork = mkDefault false;
PrivateNetwork = lib.mkDefault false;
PrivateTmp = true;
# PrivateUsers=true breaks AmbientCapabilities=CAP_NET_BIND_SERVICE
# See https://bugs.archlinux.org/task/65921
@ -265,5 +264,5 @@ in
};
};
meta.maintainers = with maintainers; [ julm ];
meta.maintainers = with lib.maintainers; [ julm ];
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.bind;
@ -14,30 +11,30 @@ let
bindZoneOptions = { name, config, ... }: {
options = {
name = mkOption {
type = types.str;
name = lib.mkOption {
type = lib.types.str;
default = name;
description = "Name of the zone.";
};
master = mkOption {
master = lib.mkOption {
description = "Master=false means slave server";
type = types.bool;
type = lib.types.bool;
};
file = mkOption {
type = types.either types.str types.path;
file = lib.mkOption {
type = lib.types.either lib.types.str lib.types.path;
description = "Zone file resource records contain columns of data, separated by whitespace, that define the record.";
};
masters = mkOption {
type = types.listOf types.str;
masters = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "List of servers for inclusion in stub and secondary zones.";
};
slaves = mkOption {
type = types.listOf types.str;
slaves = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Addresses who may request zone transfers.";
default = [ ];
};
allowQuery = mkOption {
type = types.listOf types.str;
allowQuery = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
List of address ranges allowed to query this zone. Instead of the address(es), this may instead
contain the single string "any".
@ -47,8 +44,8 @@ let
'';
default = [ "any" ];
};
extraConfig = mkOption {
type = types.str;
extraConfig = lib.mkOption {
type = lib.types.str;
description = "Extra zone config to be appended at the end of the zone section.";
default = "";
};
@ -62,16 +59,16 @@ let
inet 127.0.0.1 allow {localhost;} keys {"rndc-key";};
};
acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} };
acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} };
acl cachenetworks { ${lib.concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} };
acl badnetworks { ${lib.concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} };
options {
listen-on { ${concatMapStrings (entry: " ${entry}; ") cfg.listenOn} };
listen-on-v6 { ${concatMapStrings (entry: " ${entry}; ") cfg.listenOnIpv6} };
listen-on { ${lib.concatMapStrings (entry: " ${entry}; ") cfg.listenOn} };
listen-on-v6 { ${lib.concatMapStrings (entry: " ${entry}; ") cfg.listenOnIpv6} };
allow-query { cachenetworks; };
blackhole { badnetworks; };
forward ${cfg.forward};
forwarders { ${concatMapStrings (entry: " ${entry}; ") cfg.forwarders} };
forwarders { ${lib.concatMapStrings (entry: " ${entry}; ") cfg.forwarders} };
directory "${cfg.directory}";
pid-file "/run/named/named.pid";
${cfg.extraOptions}
@ -79,7 +76,7 @@ let
${cfg.extraConfig}
${ concatMapStrings
${ lib.concatMapStrings
({ name, file, master ? true, slaves ? [], masters ? [], allowQuery ? [], extraConfig ? "" }:
''
zone "${name}" {
@ -88,21 +85,21 @@ let
${ if master then
''
allow-transfer {
${concatMapStrings (ip: "${ip};\n") slaves}
${lib.concatMapStrings (ip: "${ip};\n") slaves}
};
''
else
''
masters {
${concatMapStrings (ip: "${ip};\n") masters}
${lib.concatMapStrings (ip: "${ip};\n") masters}
};
''
}
allow-query { ${concatMapStrings (ip: "${ip}; ") allowQuery}};
allow-query { ${lib.concatMapStrings (ip: "${ip}; ") allowQuery}};
${extraConfig}
};
'')
(attrValues cfg.zones) }
(lib.attrValues cfg.zones) }
'';
in
@ -115,14 +112,14 @@ in
services.bind = {
enable = mkEnableOption "BIND domain name server";
enable = lib.mkEnableOption "BIND domain name server";
package = mkPackageOption pkgs "bind" { };
package = lib.mkPackageOption pkgs "bind" { };
cacheNetworks = mkOption {
cacheNetworks = lib.mkOption {
default = [ "127.0.0.0/24" "::1/128" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
What networks are allowed to use us as a resolver. Note
that this is for recursive queries -- all networks are
@ -134,64 +131,64 @@ in
'';
};
blockedNetworks = mkOption {
blockedNetworks = lib.mkOption {
default = [ ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
What networks are just blocked.
'';
};
ipv4Only = mkOption {
ipv4Only = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Only use ipv4, even if the host supports ipv6.
'';
};
forwarders = mkOption {
forwarders = lib.mkOption {
default = config.networking.nameservers;
defaultText = literalExpression "config.networking.nameservers";
type = types.listOf types.str;
defaultText = lib.literalExpression "config.networking.nameservers";
type = lib.types.listOf lib.types.str;
description = ''
List of servers we should forward requests to.
'';
};
forward = mkOption {
forward = lib.mkOption {
default = "first";
type = types.enum ["first" "only"];
type = lib.types.enum ["first" "only"];
description = ''
Whether to forward 'first' (try forwarding but lookup directly if forwarding fails) or 'only'.
'';
};
listenOn = mkOption {
listenOn = lib.mkOption {
default = [ "any" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Interfaces to listen on.
'';
};
listenOnIpv6 = mkOption {
listenOnIpv6 = lib.mkOption {
default = [ "any" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Ipv6 interfaces to listen on.
'';
};
directory = mkOption {
type = types.str;
directory = lib.mkOption {
type = lib.types.str;
default = "/run/named";
description = "Working directory of BIND.";
};
zones = mkOption {
zones = lib.mkOption {
default = [ ];
type = with types; coercedTo (listOf attrs) bindZoneCoerce (attrsOf (types.submodule bindZoneOptions));
type = with lib.types; coercedTo (listOf attrs) bindZoneCoerce (attrsOf (lib.types.submodule bindZoneOptions));
description = ''
List of zones we claim authority over.
'';
@ -206,16 +203,16 @@ in
};
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra lines to be added verbatim to the generated named configuration file.
'';
};
extraOptions = mkOption {
type = types.lines;
extraOptions = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra lines to be added verbatim to the options section of the
@ -223,10 +220,10 @@ in
'';
};
configFile = mkOption {
type = types.path;
configFile = lib.mkOption {
type = lib.types.path;
default = confFile;
defaultText = literalExpression "confFile";
defaultText = lib.literalExpression "confFile";
description = ''
Overridable config file to use for named. By default, that
generated by nixos.
@ -240,9 +237,9 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
networking.resolvconf.useLocalResolver = mkDefault true;
networking.resolvconf.useLocalResolver = lib.mkDefault true;
users.users.${bindUser} =
{
@ -272,7 +269,7 @@ in
serviceConfig = {
Type = "forking"; # Set type to forking, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=900788
ExecStart = "${bindPkg.out}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile}";
ExecStart = "${bindPkg.out}/sbin/named -u ${bindUser} ${lib.optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile}";
ExecReload = "${bindPkg.out}/sbin/rndc -k '/etc/bind/rndc.key' reload";
ExecStop = "${bindPkg.out}/sbin/rndc -k '/etc/bind/rndc.key' stop";
};

View File

@ -1,176 +1,173 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.bird-lg;
stringOrConcat = sep: v: if builtins.isString v then v else concatStringsSep sep v;
stringOrConcat = sep: v: if builtins.isString v then v else lib.concatStringsSep sep v;
frontend_args = let
fe = cfg.frontend;
in {
"--servers" = concatStringsSep "," fe.servers;
"--servers" = lib.concatStringsSep "," fe.servers;
"--domain" = fe.domain;
"--listen" = fe.listenAddress;
"--proxy-port" = fe.proxyPort;
"--whois" = fe.whois;
"--dns-interface" = fe.dnsInterface;
"--bgpmap-info" = concatStringsSep "," cfg.frontend.bgpMapInfo;
"--bgpmap-info" = lib.concatStringsSep "," cfg.frontend.bgpMapInfo;
"--title-brand" = fe.titleBrand;
"--navbar-brand" = fe.navbar.brand;
"--navbar-brand-url" = fe.navbar.brandURL;
"--navbar-all-servers" = fe.navbar.allServers;
"--navbar-all-url" = fe.navbar.allServersURL;
"--net-specific-mode" = fe.netSpecificMode;
"--protocol-filter" = concatStringsSep "," cfg.frontend.protocolFilter;
"--protocol-filter" = lib.concatStringsSep "," cfg.frontend.protocolFilter;
};
proxy_args = let
px = cfg.proxy;
in {
"--allowed" = concatStringsSep "," px.allowedIPs;
"--allowed" = lib.concatStringsSep "," px.allowedIPs;
"--bird" = px.birdSocket;
"--listen" = px.listenAddress;
"--traceroute_bin" = px.traceroute.binary;
"--traceroute_flags" = concatStringsSep " " px.traceroute.flags;
"--traceroute_flags" = lib.concatStringsSep " " px.traceroute.flags;
"--traceroute_raw" = px.traceroute.rawOutput;
};
mkArgValue = value:
if isString value
then escapeShellArg value
else if isBool value
then boolToString value
if lib.isString value
then lib.escapeShellArg value
else if lib.isBool value
then lib.boolToString value
else toString value;
filterNull = filterAttrs (_: v: v != "" && v != null && v != []);
filterNull = lib.filterAttrs (_: v: v != "" && v != null && v != []);
argsAttrToList = args: mapAttrsToList (name: value: "${name} " + mkArgValue value ) (filterNull args);
argsAttrToList = args: lib.mapAttrsToList (name: value: "${name} " + mkArgValue value ) (filterNull args);
in
{
options = {
services.bird-lg = {
package = mkPackageOption pkgs "bird-lg" { };
package = lib.mkPackageOption pkgs "bird-lg" { };
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "bird-lg";
description = "User to run the service.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "bird-lg";
description = "Group to run the service.";
};
frontend = {
enable = mkEnableOption "Bird Looking Glass Frontend Webserver";
enable = lib.mkEnableOption "Bird Looking Glass Frontend Webserver";
listenAddress = mkOption {
type = types.str;
listenAddress = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:5000";
description = "Address to listen on.";
};
proxyPort = mkOption {
type = types.port;
proxyPort = lib.mkOption {
type = lib.types.port;
default = 8000;
description = "Port bird-lg-proxy is running on.";
};
domain = mkOption {
type = types.str;
domain = lib.mkOption {
type = lib.types.str;
example = "dn42.lantian.pub";
description = "Server name domain suffixes.";
};
servers = mkOption {
type = types.listOf types.str;
servers = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ "gigsgigscloud" "hostdare" ];
description = "Server name prefixes.";
};
whois = mkOption {
type = types.str;
whois = lib.mkOption {
type = lib.types.str;
default = "whois.verisign-grs.com";
description = "Whois server for queries.";
};
dnsInterface = mkOption {
type = types.str;
dnsInterface = lib.mkOption {
type = lib.types.str;
default = "asn.cymru.com";
description = "DNS zone to query ASN information.";
};
bgpMapInfo = mkOption {
type = types.listOf types.str;
bgpMapInfo = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "asn" "as-name" "ASName" "descr" ];
description = "Information displayed in bgpmap.";
};
titleBrand = mkOption {
type = types.str;
titleBrand = lib.mkOption {
type = lib.types.str;
default = "Bird-lg Go";
description = "Prefix of page titles in browser tabs.";
};
netSpecificMode = mkOption {
type = types.str;
netSpecificMode = lib.mkOption {
type = lib.types.str;
default = "";
example = "dn42";
description = "Apply network-specific changes for some networks.";
};
protocolFilter = mkOption {
type = types.listOf types.str;
protocolFilter = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "ospf" ];
description = "Information displayed in bgpmap.";
};
nameFilter = mkOption {
type = types.str;
nameFilter = lib.mkOption {
type = lib.types.str;
default = "";
example = "^ospf";
description = "Protocol names to hide in summary tables (RE2 syntax),";
};
timeout = mkOption {
type = types.int;
timeout = lib.mkOption {
type = lib.types.int;
default = 120;
description = "Time before request timed out, in seconds.";
};
navbar = {
brand = mkOption {
type = types.str;
brand = lib.mkOption {
type = lib.types.str;
default = "Bird-lg Go";
description = "Brand to show in the navigation bar .";
};
brandURL = mkOption {
type = types.str;
brandURL = lib.mkOption {
type = lib.types.str;
default = "/";
description = "URL of the brand to show in the navigation bar.";
};
allServers = mkOption {
type = types.str;
allServers = lib.mkOption {
type = lib.types.str;
default = "ALL Servers";
description = "Text of 'All server' button in the navigation bar.";
};
allServersURL = mkOption {
type = types.str;
allServersURL = lib.mkOption {
type = lib.types.str;
default = "all";
description = "URL of 'All servers' button.";
};
};
extraArgs = mkOption {
type = with types; either lines (listOf str);
extraArgs = lib.mkOption {
type = with lib.types; either lines (listOf str);
default = [ ];
description = ''
Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#frontend).
@ -183,50 +180,50 @@ in
};
proxy = {
enable = mkEnableOption "Bird Looking Glass Proxy";
enable = lib.mkEnableOption "Bird Looking Glass Proxy";
listenAddress = mkOption {
type = types.str;
listenAddress = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:8000";
description = "Address to listen on.";
};
allowedIPs = mkOption {
type = types.listOf types.str;
allowedIPs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "192.168.25.52" "192.168.25.53" "192.168.0.0/24" ];
description = "List of IPs or networks to allow (default all allowed).";
};
birdSocket = mkOption {
type = types.str;
birdSocket = lib.mkOption {
type = lib.types.str;
default = "/var/run/bird/bird.ctl";
description = "Bird control socket path.";
};
traceroute = {
binary = mkOption {
type = types.str;
binary = lib.mkOption {
type = lib.types.str;
default = "${pkgs.traceroute}/bin/traceroute";
defaultText = literalExpression ''"''${pkgs.traceroute}/bin/traceroute"'';
defaultText = lib.literalExpression ''"''${pkgs.traceroute}/bin/traceroute"'';
description = "Traceroute's binary path.";
};
flags = mkOption {
type = with types; listOf str;
flags = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
description = "Flags for traceroute process";
};
rawOutput = mkOption {
type = types.bool;
rawOutput = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Display traceroute output in raw format.";
};
};
extraArgs = mkOption {
type = with types; either lines (listOf str);
extraArgs = lib.mkOption {
type = with lib.types; either lines (listOf str);
default = [ ];
description = ''
Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#proxy).
@ -254,7 +251,7 @@ in
;
systemd.services = {
bird-lg-frontend = mkIf cfg.frontend.enable {
bird-lg-frontend = lib.mkIf cfg.frontend.enable {
enable = true;
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
@ -270,12 +267,12 @@ in
};
script = ''
${cfg.package}/bin/frontend \
${concatStringsSep " \\\n " (argsAttrToList frontend_args)} \
${lib.concatStringsSep " \\\n " (argsAttrToList frontend_args)} \
${stringOrConcat " " cfg.frontend.extraArgs}
'';
};
bird-lg-proxy = mkIf cfg.proxy.enable {
bird-lg-proxy = lib.mkIf cfg.proxy.enable {
enable = true;
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
@ -291,14 +288,14 @@ in
};
script = ''
${cfg.package}/bin/proxy \
${concatStringsSep " \\\n " (argsAttrToList proxy_args)} \
${lib.concatStringsSep " \\\n " (argsAttrToList proxy_args)} \
${stringOrConcat " " cfg.proxy.extraArgs}
'';
};
};
users = mkIf (cfg.frontend.enable || cfg.proxy.enable) {
groups."bird-lg" = mkIf (cfg.group == "bird-lg") { };
users."bird-lg" = mkIf (cfg.user == "bird-lg") {
users = lib.mkIf (cfg.frontend.enable || cfg.proxy.enable) {
groups."bird-lg" = lib.mkIf (cfg.group == "bird-lg") { };
users."bird-lg" = lib.mkIf (cfg.user == "bird-lg") {
description = "Bird Looking Glass user";
extraGroups = lib.optionals (config.services.bird2.enable) [ "bird2" ];
group = cfg.group;

View File

@ -1,31 +1,28 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.birdwatcher;
in
{
options = {
services.birdwatcher = {
package = mkPackageOption pkgs "birdwatcher" { };
enable = mkEnableOption "Birdwatcher";
flags = mkOption {
package = lib.mkPackageOption pkgs "birdwatcher" { };
enable = lib.mkEnableOption "Birdwatcher";
flags = lib.mkOption {
default = [ ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
example = [ "-worker-pool-size 16" "-6" ];
description = ''
Flags to append to the program call
'';
};
settings = mkOption {
type = types.lines;
settings = lib.mkOption {
type = lib.types.lines;
default = { };
description = ''
birdwatcher configuration, for configuration options see the example on [github](https://github.com/alice-lg/birdwatcher/blob/master/etc/birdwatcher/birdwatcher.conf)
'';
example = literalExpression ''
example = lib.literalExpression ''
[server]
allow_from = []
allow_uncached = false
@ -72,7 +69,7 @@ in
};
config =
let flagsStr = escapeShellArgs cfg.flags;
let flagsStr = lib.escapeShellArgs cfg.flags;
in lib.mkIf cfg.enable {
environment.etc."birdwatcher/birdwatcher.conf".source = pkgs.writeTextFile {
name = "birdwatcher.conf";

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.bitlbee;
@ -46,8 +43,8 @@ in
services.bitlbee = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to run the BitlBee IRC to other chat network gateway.
@ -56,8 +53,8 @@ in
'';
};
interface = mkOption {
type = types.str;
interface = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
The interface the BitlBee daemon will be listening to. If `127.0.0.1`,
@ -66,17 +63,17 @@ in
'';
};
portNumber = mkOption {
portNumber = lib.mkOption {
default = 6667;
type = types.port;
type = lib.types.port;
description = ''
Number of the port BitlBee will be listening to.
'';
};
authBackend = mkOption {
authBackend = lib.mkOption {
default = "storage";
type = types.enum [ "storage" "pam" ];
type = lib.types.enum [ "storage" "pam" ];
description = ''
How users are authenticated
storage -- save passwords internally
@ -84,9 +81,9 @@ in
'';
};
authMode = mkOption {
authMode = lib.mkOption {
default = "Open";
type = types.enum [ "Open" "Closed" "Registered" ];
type = lib.types.enum [ "Open" "Closed" "Registered" ];
description = ''
The following authentication modes are available:
Open -- Accept connections from anyone, use NickServ for user authentication.
@ -95,9 +92,9 @@ in
'';
};
hostName = mkOption {
hostName = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = ''
Normally, BitlBee gets a hostname using getsockname(). If you have a nicer
alias for your BitlBee daemon, you can set it here and BitlBee will identify
@ -105,53 +102,53 @@ in
'';
};
plugins = mkOption {
type = types.listOf types.package;
plugins = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
example = literalExpression "[ pkgs.bitlbee-facebook ]";
example = lib.literalExpression "[ pkgs.bitlbee-facebook ]";
description = ''
The list of bitlbee plugins to install.
'';
};
libpurple_plugins = mkOption {
type = types.listOf types.package;
libpurple_plugins = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
example = literalExpression "[ pkgs.purple-matrix ]";
example = lib.literalExpression "[ pkgs.purple-matrix ]";
description = ''
The list of libpurple plugins to install.
'';
};
configDir = mkOption {
configDir = lib.mkOption {
default = "/var/lib/bitlbee";
type = types.path;
type = lib.types.path;
description = ''
Specify an alternative directory to store all the per-user configuration
files.
'';
};
protocols = mkOption {
protocols = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = ''
This option allows to remove the support of protocol, even if compiled
in. If nothing is given, there are no restrictions.
'';
};
extraSettings = mkOption {
extraSettings = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Will be inserted in the Settings section of the config file.
'';
};
extraDefaults = mkOption {
extraDefaults = lib.mkOption {
default = "";
type = types.lines;
type = lib.types.lines;
description = ''
Will be inserted in the Default section of the config file.
'';
@ -163,8 +160,8 @@ in
###### implementation
config = mkMerge [
(mkIf config.services.bitlbee.enable {
config = lib.mkMerge [
(lib.mkIf config.services.bitlbee.enable {
systemd.services.bitlbee = {
environment.PURPLE_PLUGIN_PATH = purple_plugin_path;
description = "BitlBee IRC to other chat networks gateway";
@ -182,7 +179,7 @@ in
environment.systemPackages = [ bitlbeePkg ];
})
(mkIf (config.services.bitlbee.authBackend == "pam") {
(lib.mkIf (config.services.bitlbee.authBackend == "pam") {
security.pam.services.bitlbee = {};
})
];

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
eachBlockbook = config.services.blockbook-frontend;
@ -10,24 +7,24 @@ let
options = {
enable = mkEnableOption "blockbook-frontend application";
enable = lib.mkEnableOption "blockbook-frontend application";
package = mkPackageOption pkgs "blockbook" { };
package = lib.mkPackageOption pkgs "blockbook" { };
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "blockbook-frontend-${name}";
description = "The user as which to run blockbook-frontend-${name}.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "${config.user}";
description = "The group as which to run blockbook-frontend-${name}.";
};
certFile = mkOption {
type = types.nullOr types.path;
certFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = "/etc/secrets/blockbook-frontend-${name}/certFile";
description = ''
@ -36,15 +33,15 @@ let
'';
};
configFile = mkOption {
type = with types; nullOr path;
configFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
example = "${config.dataDir}/config.json";
description = "Location of the blockbook configuration file.";
};
coinName = mkOption {
type = types.str;
coinName = lib.mkOption {
type = lib.types.str;
default = "Bitcoin";
description = ''
See <https://github.com/trezor/blockbook/blob/master/bchain/coins/blockchain.go#L61>
@ -52,68 +49,68 @@ let
'';
};
cssDir = mkOption {
type = types.path;
cssDir = lib.mkOption {
type = lib.types.path;
default = "${config.package}/share/css/";
defaultText = literalExpression ''"''${package}/share/css/"'';
example = literalExpression ''"''${dataDir}/static/css/"'';
defaultText = lib.literalExpression ''"''${package}/share/css/"'';
example = lib.literalExpression ''"''${dataDir}/static/css/"'';
description = ''
Location of the dir with {file}`main.css` CSS file.
By default, the one shipped with the package is used.
'';
};
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/blockbook-frontend-${name}";
description = "Location of blockbook-frontend-${name} data directory.";
};
debug = mkOption {
type = types.bool;
debug = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Debug mode, return more verbose errors, reload templates on each request.";
};
internal = mkOption {
type = types.nullOr types.str;
internal = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = ":9030";
description = "Internal http server binding `[address]:port`.";
};
messageQueueBinding = mkOption {
type = types.str;
messageQueueBinding = lib.mkOption {
type = lib.types.str;
default = "tcp://127.0.0.1:38330";
description = "Message Queue Binding `address:port`.";
};
public = mkOption {
type = types.nullOr types.str;
public = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = ":9130";
description = "Public http server binding `[address]:port`.";
};
rpc = {
url = mkOption {
type = types.str;
url = lib.mkOption {
type = lib.types.str;
default = "http://127.0.0.1";
description = "URL for JSON-RPC connections.";
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 8030;
description = "Port for JSON-RPC connections.";
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "rpc";
description = "Username for JSON-RPC connections.";
};
password = mkOption {
type = types.str;
password = lib.mkOption {
type = lib.types.str;
default = "rpc";
description = ''
RPC password for JSON-RPC connections.
@ -122,8 +119,8 @@ let
'';
};
passwordFile = mkOption {
type = types.nullOr types.path;
passwordFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
File containing password of the RPC user.
@ -132,24 +129,24 @@ let
};
};
sync = mkOption {
type = types.bool;
sync = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Synchronizes until tip, if together with zeromq, keeps index synchronized.";
};
templateDir = mkOption {
type = types.path;
templateDir = lib.mkOption {
type = lib.types.path;
default = "${config.package}/share/templates/";
defaultText = literalExpression ''"''${package}/share/templates/"'';
example = literalExpression ''"''${dataDir}/templates/static/"'';
defaultText = lib.literalExpression ''"''${package}/share/templates/"'';
example = lib.literalExpression ''"''${dataDir}/templates/static/"'';
description = "Location of the HTML templates. By default, ones shipped with the package are used.";
};
extraConfig = mkOption {
type = types.attrs;
extraConfig = lib.mkOption {
type = lib.types.attrs;
default = {};
example = literalExpression '' {
example = lib.literalExpression '' {
"alternative_estimate_fee" = "whatthefee-disabled";
"alternative_estimate_fee_params" = "{\"url\": \"https://whatthefee.io/data.json\", \"periodSeconds\": 60}";
"fiat_rates" = "coingecko";
@ -174,8 +171,8 @@ let
'';
};
extraCmdLineOptions = mkOption {
type = types.listOf types.str;
extraCmdLineOptions = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = [ "-workers=1" "-dbcache=0" "-logtosderr" ];
description = ''
@ -190,8 +187,8 @@ in
# interface
options = {
services.blockbook-frontend = mkOption {
type = types.attrsOf (types.submodule blockbookOpts);
services.blockbook-frontend = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule blockbookOpts);
default = {};
description = "Specification of one or more blockbook-frontend instances.";
};
@ -199,10 +196,10 @@ in
# implementation
config = mkIf (eachBlockbook != {}) {
config = lib.mkIf (eachBlockbook != {}) {
systemd.services = mapAttrs' (blockbookName: cfg: (
nameValuePair "blockbook-frontend-${blockbookName}" (
systemd.services = lib.mapAttrs' (blockbookName: cfg: (
lib.nameValuePair "blockbook-frontend-${blockbookName}" (
let
configFile = if cfg.configFile != null then cfg.configFile else
pkgs.writeText "config.conf" (builtins.toJSON ( {
@ -220,7 +217,7 @@ in
preStart = ''
ln -sf ${cfg.templateDir} ${cfg.dataDir}/static/
ln -sf ${cfg.cssDir} ${cfg.dataDir}/static/
${optionalString (cfg.rpc.passwordFile != null && cfg.configFile == null) ''
${lib.optionalString (cfg.rpc.passwordFile != null && cfg.configFile == null) ''
CONFIGTMP=$(mktemp)
${pkgs.jq}/bin/jq ".rpc_pass = \"$(cat ${cfg.rpc.passwordFile})\"" ${configFile} > $CONFIGTMP
mv $CONFIGTMP ${cfg.dataDir}/${blockbookName}-config.json
@ -237,11 +234,11 @@ in
"-blockchaincfg=${configFile}"
} \
-datadir=${cfg.dataDir} \
${optionalString (cfg.sync != false) "-sync"} \
${optionalString (cfg.certFile != null) "-certfile=${toString cfg.certFile}"} \
${optionalString (cfg.debug != false) "-debug"} \
${optionalString (cfg.internal != null) "-internal=${toString cfg.internal}"} \
${optionalString (cfg.public != null) "-public=${toString cfg.public}"} \
${lib.optionalString (cfg.sync != false) "-sync"} \
${lib.optionalString (cfg.certFile != null) "-certfile=${toString cfg.certFile}"} \
${lib.optionalString (cfg.debug != false) "-debug"} \
${lib.optionalString (cfg.internal != null) "-internal=${toString cfg.internal}"} \
${lib.optionalString (cfg.public != null) "-public=${toString cfg.public}"} \
${toString cfg.extraCmdLineOptions}
'';
Restart = "on-failure";
@ -251,23 +248,23 @@ in
}
) )) eachBlockbook;
systemd.tmpfiles.rules = flatten (mapAttrsToList (blockbookName: cfg: [
systemd.tmpfiles.rules = lib.flatten (lib.mapAttrsToList (blockbookName: cfg: [
"d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -"
"d ${cfg.dataDir}/static 0750 ${cfg.user} ${cfg.group} - -"
]) eachBlockbook);
users.users = mapAttrs' (blockbookName: cfg: (
nameValuePair "blockbook-frontend-${blockbookName}" {
users.users = lib.mapAttrs' (blockbookName: cfg: (
lib.nameValuePair "blockbook-frontend-${blockbookName}" {
name = cfg.user;
group = cfg.group;
home = cfg.dataDir;
isSystemUser = true;
})) eachBlockbook;
users.groups = mapAttrs' (instanceName: cfg: (
nameValuePair "${cfg.group}" { })) eachBlockbook;
users.groups = lib.mapAttrs' (instanceName: cfg: (
lib.nameValuePair "${cfg.group}" { })) eachBlockbook;
};
meta.maintainers = with maintainers; [ _1000101 ];
meta.maintainers = with lib.maintainers; [ _1000101 ];
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.blocky;
@ -10,11 +7,11 @@ let
in
{
options.services.blocky = {
enable = mkEnableOption "blocky, a fast and lightweight DNS proxy as ad-blocker for local network with many features";
enable = lib.mkEnableOption "blocky, a fast and lightweight DNS proxy as ad-blocker for local network with many features";
package = mkPackageOption pkgs "blocky" { };
package = lib.mkPackageOption pkgs "blocky" { };
settings = mkOption {
settings = lib.mkOption {
type = format.type;
default = { };
description = ''
@ -25,14 +22,14 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.blocky = {
description = "A DNS proxy and ad-blocker for the local network";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = true;
ExecStart = "${getExe cfg.package} --config ${configFile}";
ExecStart = "${lib.getExe cfg.package} --config ${configFile}";
Restart = "on-failure";
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];

View File

@ -1,14 +1,11 @@
{ config, lib, pkgs, ...}:
with lib;
let
cfgs = config.services.cgit;
settingType = with types; oneOf [ bool int str ];
repeatedSettingType = with types; oneOf [ settingType (listOf settingType) ];
settingType = with lib.types; oneOf [ bool int str ];
repeatedSettingType = with lib.types; oneOf [ settingType (listOf settingType) ];
genAttrs' = names: f: listToAttrs (map f names);
genAttrs' = names: f: lib.listToAttrs (map f names);
regexEscape =
let
@ -20,9 +17,9 @@ let
" " # \f / 0x0C
];
in
replaceStrings special (map (c: "\\${c}") special);
lib.replaceStrings special (map (c: "\\${c}") special);
stripLocation = cfg: removeSuffix "/" cfg.nginx.location;
stripLocation = cfg: lib.removeSuffix "/" cfg.nginx.location;
regexLocation = cfg: regexEscape (stripLocation cfg);
@ -47,29 +44,29 @@ let
# list value as multiple lines (for "readme" for example)
cgitrcEntry = name: value:
if isList value then
if lib.isList value then
map (cgitrcLine name) value
else
[ (cgitrcLine name value) ];
mkCgitrc = cfg: pkgs.writeText "cgitrc" ''
# global settings
${concatStringsSep "\n" (
flatten (mapAttrsToList
${lib.concatStringsSep "\n" (
lib.flatten (lib.mapAttrsToList
cgitrcEntry
({ virtual-root = cfg.nginx.location; } // cfg.settings)
)
)
}
${optionalString (cfg.scanPath != null) (cgitrcLine "scan-path" cfg.scanPath)}
${lib.optionalString (cfg.scanPath != null) (cgitrcLine "scan-path" cfg.scanPath)}
# repository settings
${concatStrings (
mapAttrsToList
${lib.concatStrings (
lib.mapAttrsToList
(url: settings: ''
${cgitrcLine "repo.url" url}
${concatStringsSep "\n" (
mapAttrsToList (name: cgitrcLine "repo.${name}") settings
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (name: cgitrcLine "repo.${name}") settings
)
}
'')
@ -90,32 +87,32 @@ let
in
{
options = {
services.cgit = mkOption {
services.cgit = lib.mkOption {
description = "Configure cgit instances.";
default = {};
type = types.attrsOf (types.submodule ({ config, ... }: {
type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: {
options = {
enable = mkEnableOption "cgit";
enable = lib.mkEnableOption "cgit";
package = mkPackageOption pkgs "cgit" {};
package = lib.mkPackageOption pkgs "cgit" {};
nginx.virtualHost = mkOption {
nginx.virtualHost = lib.mkOption {
description = "VirtualHost to serve cgit on, defaults to the attribute name.";
type = types.str;
type = lib.types.str;
default = config._module.args.name;
example = "git.example.com";
};
nginx.location = mkOption {
nginx.location = lib.mkOption {
description = "Location to serve cgit under.";
type = types.str;
type = lib.types.str;
default = "/";
example = "/git/";
};
repos = mkOption {
repos = lib.mkOption {
description = "cgit repository settings, see cgitrc(5)";
type = with types; attrsOf (attrsOf settingType);
type = with lib.types; attrsOf (attrsOf settingType);
default = {};
example = {
blah = {
@ -125,18 +122,18 @@ in
};
};
scanPath = mkOption {
scanPath = lib.mkOption {
description = "A path which will be scanned for repositories.";
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
default = null;
example = "/var/lib/git";
};
settings = mkOption {
settings = lib.mkOption {
description = "cgit configuration, see cgitrc(5)";
type = types.attrsOf repeatedSettingType;
type = lib.types.attrsOf repeatedSettingType;
default = {};
example = literalExpression ''
example = lib.literalExpression ''
{
enable-follow-links = true;
source-filter = "''${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py";
@ -144,21 +141,21 @@ in
'';
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
description = "These lines go to the end of cgitrc verbatim.";
type = types.lines;
type = lib.types.lines;
default = "";
};
user = mkOption {
user = lib.mkOption {
description = "User to run the cgit service as.";
type = types.str;
type = lib.types.str;
default = "cgit";
};
group = mkOption {
group = lib.mkOption {
description = "Group to run the cgit service as.";
type = types.str;
type = lib.types.str;
default = "cgit";
};
};
@ -166,13 +163,13 @@ in
};
};
config = mkIf (any (cfg: cfg.enable) (attrValues cfgs)) {
assertions = mapAttrsToList (vhost: cfg: {
config = lib.mkIf (lib.any (cfg: cfg.enable) (lib.attrValues cfgs)) {
assertions = lib.mapAttrsToList (vhost: cfg: {
assertion = !cfg.enable || (cfg.scanPath == null) != (cfg.repos == {});
message = "Exactly one of services.cgit.${vhost}.scanPath or services.cgit.${vhost}.repos must be set.";
}) cfgs;
users = mkMerge (flip mapAttrsToList cfgs (_: cfg: {
users = lib.mkMerge (lib.flip lib.mapAttrsToList cfgs (_: cfg: {
users.${cfg.user} = {
isSystemUser = true;
inherit (cfg) group;
@ -180,23 +177,23 @@ in
groups.${cfg.group} = { };
}));
services.fcgiwrap.instances = flip mapAttrs' cfgs (name: cfg:
nameValuePair "cgit-${name}" {
services.fcgiwrap.instances = lib.flip lib.mapAttrs' cfgs (name: cfg:
lib.nameValuePair "cgit-${name}" {
process = { inherit (cfg) user group; };
socket = { inherit (config.services.nginx) user group; };
}
);
systemd.services = flip mapAttrs' cfgs (name: cfg:
nameValuePair (fcgiwrapUnitName name)
(mkIf (cfg.repos != { }) {
systemd.services = lib.flip lib.mapAttrs' cfgs (name: cfg:
lib.nameValuePair (fcgiwrapUnitName name)
(lib.mkIf (cfg.repos != { }) {
serviceConfig.RuntimeDirectory = fcgiwrapUnitName name;
preStart = ''
GIT_PROJECT_ROOT=${escapeShellArg (gitProjectRoot name cfg)}
GIT_PROJECT_ROOT=${lib.escapeShellArg (gitProjectRoot name cfg)}
mkdir -p "$GIT_PROJECT_ROOT"
cd "$GIT_PROJECT_ROOT"
${concatLines (flip mapAttrsToList cfg.repos (name: repo: ''
ln -s ${escapeShellArg repo.path} ${escapeShellArg name}
${lib.concatLines (lib.flip lib.mapAttrsToList cfg.repos (name: repo: ''
ln -s ${lib.escapeShellArg repo.path} ${lib.escapeShellArg name}
''))}
'';
}
@ -204,12 +201,12 @@ in
services.nginx.enable = true;
services.nginx.virtualHosts = mkMerge (mapAttrsToList (name: cfg: {
services.nginx.virtualHosts = lib.mkMerge (lib.mapAttrsToList (name: cfg: {
${cfg.nginx.virtualHost} = {
locations = (
genAttrs'
[ "cgit.css" "cgit.png" "favicon.ico" "robots.txt" ]
(fileName: nameValuePair "= ${stripLocation cfg}/${fileName}" {
(fileName: lib.nameValuePair "= ${stripLocation cfg}/${fileName}" {
extraConfig = ''
alias ${cfg.package}/cgit/${fileName};
'';

View File

@ -1,69 +1,66 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.chisel-server;
in {
options = {
services.chisel-server = {
enable = mkEnableOption "Chisel Tunnel Server";
host = mkOption {
enable = lib.mkEnableOption "Chisel Tunnel Server";
host = lib.mkOption {
description = "Address to listen on, falls back to 0.0.0.0";
type = with types; nullOr str;
type = with lib.types; nullOr str;
default = null;
example = "[::1]";
};
port = mkOption {
port = lib.mkOption {
description = "Port to listen on, falls back to 8080";
type = with types; nullOr port;
type = with lib.types; nullOr port;
default = null;
};
authfile = mkOption {
authfile = lib.mkOption {
description = "Path to auth.json file";
type = with types; nullOr path;
type = with lib.types; nullOr path;
default = null;
};
keepalive = mkOption {
keepalive = lib.mkOption {
description = "Keepalive interval, falls back to 25s";
type = with types; nullOr str;
type = with lib.types; nullOr str;
default = null;
example = "5s";
};
backend = mkOption {
backend = lib.mkOption {
description = "HTTP server to proxy normal requests to";
type = with types; nullOr str;
type = with lib.types; nullOr str;
default = null;
example = "http://127.0.0.1:8888";
};
socks5 = mkOption {
socks5 = lib.mkOption {
description = "Allow clients access to internal SOCKS5 proxy";
type = types.bool;
type = lib.types.bool;
default = false;
};
reverse = mkOption {
reverse = lib.mkOption {
description = "Allow clients reverse port forwarding";
type = types.bool;
type = lib.types.bool;
default = false;
};
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.chisel-server = {
description = "Chisel Tunnel Server";
wantedBy = [ "network-online.target" ];
serviceConfig = {
ExecStart = "${pkgs.chisel}/bin/chisel server " + concatStringsSep " " (
optional (cfg.host != null) "--host ${cfg.host}"
++ optional (cfg.port != null) "--port ${builtins.toString cfg.port}"
++ optional (cfg.authfile != null) "--authfile ${cfg.authfile}"
++ optional (cfg.keepalive != null) "--keepalive ${cfg.keepalive}"
++ optional (cfg.backend != null) "--backend ${cfg.backend}"
++ optional cfg.socks5 "--socks5"
++ optional cfg.reverse "--reverse"
ExecStart = "${pkgs.chisel}/bin/chisel server " + lib.concatStringsSep " " (
lib.optional (cfg.host != null) "--host ${cfg.host}"
++ lib.optional (cfg.port != null) "--port ${builtins.toString cfg.port}"
++ lib.optional (cfg.authfile != null) "--authfile ${cfg.authfile}"
++ lib.optional (cfg.keepalive != null) "--keepalive ${cfg.keepalive}"
++ lib.optional (cfg.backend != null) "--backend ${cfg.backend}"
++ lib.optional cfg.socks5 "--socks5"
++ lib.optional cfg.reverse "--reverse"
);
# Security Hardening
@ -95,5 +92,5 @@ in {
};
};
meta.maintainers = with maintainers; [ clerie ];
meta.maintainers = with lib.maintainers; [ clerie ];
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
pkg = pkgs.cjdns;
@ -11,28 +8,28 @@ let
connectToSubmodule =
{ ... }:
{ options =
{ password = mkOption {
type = types.str;
{ password = lib.mkOption {
type = lib.types.str;
description = "Authorized password to the opposite end of the tunnel.";
};
login = mkOption {
login = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = "(optional) name your peer has for you";
};
peerName = mkOption {
peerName = lib.mkOption {
default = "";
type = types.str;
type = lib.types.str;
description = "(optional) human-readable name for peer";
};
publicKey = mkOption {
type = types.str;
publicKey = lib.mkOption {
type = lib.types.str;
description = "Public key at the opposite end of the tunnel.";
};
hostname = mkOption {
hostname = lib.mkOption {
default = "";
example = "foobar.hype";
type = types.str;
type = lib.types.str;
description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures.";
};
};
@ -41,16 +38,16 @@ let
# Additional /etc/hosts entries for peers with an associated hostname
cjdnsExtraHosts = pkgs.runCommand "cjdns-hosts" {} ''
exec >$out
${concatStringsSep "\n" (mapAttrsToList (k: v:
optionalString (v.hostname != "")
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v:
lib.optionalString (v.hostname != "")
"echo $(${pkgs.cjdns}/bin/publictoip6 ${v.publicKey}) ${v.hostname}")
(cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))}
'';
parseModules = x:
x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
x // { connectTo = lib.mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
cjdrouteConf = builtins.toJSON ( recursiveUpdate {
cjdrouteConf = builtins.toJSON ( lib.recursiveUpdate {
admin = {
bind = cfg.admin.bind;
password = "@CJDNS_ADMIN_PASSWORD@";
@ -84,8 +81,8 @@ in
services.cjdns = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the cjdns network encryption
@ -95,8 +92,8 @@ in
'';
};
extraConfig = mkOption {
type = types.attrs;
extraConfig = lib.mkOption {
type = lib.types.attrs;
default = {};
example = { router.interface.tunDevice = "tun10"; };
description = ''
@ -105,8 +102,8 @@ in
'';
};
confFile = mkOption {
type = types.nullOr types.path;
confFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = "/etc/cjdroute.conf";
description = ''
@ -114,8 +111,8 @@ in
'';
};
authorizedPasswords = mkOption {
type = types.listOf types.str;
authorizedPasswords = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [
"snyrfgkqsc98qh1y4s5hbu0j57xw5s0"
@ -129,8 +126,8 @@ in
};
admin = {
bind = mkOption {
type = types.str;
bind = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:11234";
description = ''
Bind the administration port to this address and port.
@ -139,18 +136,18 @@ in
};
UDPInterface = {
bind = mkOption {
type = types.str;
bind = lib.mkOption {
type = lib.types.str;
default = "";
example = "192.168.1.32:43211";
description = ''
Address and port to bind UDP tunnels to.
'';
};
connectTo = mkOption {
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
connectTo = lib.mkOption {
type = lib.types.attrsOf ( lib.types.submodule ( connectToSubmodule ) );
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
"192.168.1.1:27313" = {
hostname = "homer.hype";
@ -166,8 +163,8 @@ in
};
ETHInterface = {
bind = mkOption {
type = types.str;
bind = lib.mkOption {
type = lib.types.str;
default = "";
example = "eth0";
description = ''
@ -176,8 +173,8 @@ in
'';
};
beacon = mkOption {
type = types.int;
beacon = lib.mkOption {
type = lib.types.int;
default = 2;
description = ''
Auto-connect to other cjdns nodes on the same network.
@ -193,10 +190,10 @@ in
'';
};
connectTo = mkOption {
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
connectTo = lib.mkOption {
type = lib.types.attrsOf ( lib.types.submodule ( connectToSubmodule ) );
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
"01:02:03:04:05:06" = {
hostname = "homer.hype";
@ -212,8 +209,8 @@ in
};
};
addExtraHosts = mkOption {
type = types.bool;
addExtraHosts = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to add cjdns peers with an associated hostname to
@ -226,7 +223,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
boot.kernelModules = [ "tun" ];
@ -238,7 +235,7 @@ in
after = [ "network-online.target" ];
bindsTo = [ "network-online.target" ];
preStart = optionalString (cfg.confFile == null) ''
preStart = lib.optionalString (cfg.confFile == null) ''
[ -e /etc/cjdns.keys ] && source /etc/cjdns.keys
if [ -z "$CJDNS_PRIVATE_KEY" ]; then
@ -283,7 +280,7 @@ in
};
};
networking.hostFiles = mkIf cfg.addExtraHosts [ cjdnsExtraHosts ];
networking.hostFiles = lib.mkIf cfg.addExtraHosts [ cjdnsExtraHosts ];
assertions = [
{ assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.clatd;
@ -11,16 +9,16 @@ in
{
options = {
services.clatd = {
enable = mkEnableOption "clatd";
enable = lib.mkEnableOption "clatd";
package = mkPackageOption pkgs "clatd" { };
package = lib.mkPackageOption pkgs "clatd" { };
settings = mkOption {
type = types.submodule ({ name, ... }: {
settings = lib.mkOption {
type = lib.types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
});
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
plat-prefix = "64:ff9b::/96";
}
@ -32,7 +30,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.clatd = {
description = "464XLAT CLAT daemon";
documentation = [ "man:clatd(8)" ];

View File

@ -1,19 +1,16 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.cloudflare-dyndns;
in
{
options = {
services.cloudflare-dyndns = {
enable = mkEnableOption "Cloudflare Dynamic DNS Client";
enable = lib.mkEnableOption "Cloudflare Dynamic DNS Client";
package = mkPackageOption pkgs "cloudflare-dyndns" { };
package = lib.mkPackageOption pkgs "cloudflare-dyndns" { };
apiTokenFile = mkOption {
type = types.nullOr types.str;
apiTokenFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The path to a file containing the CloudFlare API token.
@ -22,16 +19,16 @@ in
'';
};
domains = mkOption {
type = types.listOf types.str;
domains = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
List of domain names to update records for.
'';
};
frequency = mkOption {
type = types.nullOr types.str;
frequency = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "*:0/5";
description = ''
Run cloudflare-dyndns with the given frequency (see
@ -40,32 +37,32 @@ in
'';
};
proxied = mkOption {
type = types.bool;
proxied = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether this is a DNS-only record, or also being proxied through CloudFlare.
'';
};
ipv4 = mkOption {
type = types.bool;
ipv4 = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable setting IPv4 A records.
'';
};
ipv6 = mkOption {
type = types.bool;
ipv6 = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable setting IPv6 AAAA records.
'';
};
deleteMissing = mkOption {
type = types.bool;
deleteMissing = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to delete the record when no IP address is found.
@ -74,7 +71,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.cloudflare-dyndns = {
description = "CloudFlare Dynamic DNS Client";
after = [ "network.target" ];
@ -94,12 +91,12 @@ in
args = [ "--cache-file /var/lib/cloudflare-dyndns/ip.cache" ]
++ (if cfg.ipv4 then [ "-4" ] else [ "-no-4" ])
++ (if cfg.ipv6 then [ "-6" ] else [ "-no-6" ])
++ optional cfg.deleteMissing "--delete-missing"
++ optional cfg.proxied "--proxied";
++ lib.optional cfg.deleteMissing "--delete-missing"
++ lib.optional cfg.proxied "--proxied";
in
"${getExe cfg.package} ${toString args}";
"${lib.getExe cfg.package} ${toString args}";
};
} // optionalAttrs (cfg.frequency != null) {
} // lib.optionalAttrs (cfg.frequency != null) {
startAt = cfg.frequency;
};
};

View File

@ -1,13 +1,10 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.cloudflared;
originRequest = {
connectTimeout = mkOption {
type = with types; nullOr str;
connectTimeout = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "30s";
description = ''
@ -15,8 +12,8 @@ let
'';
};
tlsTimeout = mkOption {
type = with types; nullOr str;
tlsTimeout = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "10s";
description = ''
@ -24,8 +21,8 @@ let
'';
};
tcpKeepAlive = mkOption {
type = with types; nullOr str;
tcpKeepAlive = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "30s";
description = ''
@ -33,8 +30,8 @@ let
'';
};
noHappyEyeballs = mkOption {
type = with types; nullOr bool;
noHappyEyeballs = lib.mkOption {
type = with lib.types; nullOr bool;
default = null;
example = false;
description = ''
@ -42,8 +39,8 @@ let
'';
};
keepAliveConnections = mkOption {
type = with types; nullOr int;
keepAliveConnections = lib.mkOption {
type = with lib.types; nullOr int;
default = null;
example = 100;
description = ''
@ -51,8 +48,8 @@ let
'';
};
keepAliveTimeout = mkOption {
type = with types; nullOr str;
keepAliveTimeout = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "1m30s";
description = ''
@ -60,8 +57,8 @@ let
'';
};
httpHostHeader = mkOption {
type = with types; nullOr str;
httpHostHeader = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "";
description = ''
@ -69,8 +66,8 @@ let
'';
};
originServerName = mkOption {
type = with types; nullOr str;
originServerName = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "";
description = ''
@ -78,8 +75,8 @@ let
'';
};
caPool = mkOption {
type = with types; nullOr (either str path);
caPool = lib.mkOption {
type = with lib.types; nullOr (either str path);
default = null;
example = "";
description = ''
@ -87,8 +84,8 @@ let
'';
};
noTLSVerify = mkOption {
type = with types; nullOr bool;
noTLSVerify = lib.mkOption {
type = with lib.types; nullOr bool;
default = null;
example = false;
description = ''
@ -96,8 +93,8 @@ let
'';
};
disableChunkedEncoding = mkOption {
type = with types; nullOr bool;
disableChunkedEncoding = lib.mkOption {
type = with lib.types; nullOr bool;
default = null;
example = false;
description = ''
@ -105,8 +102,8 @@ let
'';
};
proxyAddress = mkOption {
type = with types; nullOr str;
proxyAddress = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "127.0.0.1";
description = ''
@ -114,8 +111,8 @@ let
'';
};
proxyPort = mkOption {
type = with types; nullOr int;
proxyPort = lib.mkOption {
type = with lib.types; nullOr int;
default = null;
example = 0;
description = ''
@ -123,8 +120,8 @@ let
'';
};
proxyType = mkOption {
type = with types; nullOr (enum [ "" "socks" ]);
proxyType = lib.mkOption {
type = with lib.types; nullOr (enum [ "" "socks" ]);
default = null;
example = "";
description = ''
@ -138,32 +135,32 @@ let
in
{
options.services.cloudflared = {
enable = mkEnableOption "Cloudflare Tunnel client daemon (formerly Argo Tunnel)";
enable = lib.mkEnableOption "Cloudflare Tunnel client daemon (formerly Argo Tunnel)";
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "cloudflared";
description = "User account under which Cloudflared runs.";
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "cloudflared";
description = "Group under which cloudflared runs.";
};
package = mkPackageOption pkgs "cloudflared" { };
package = lib.mkPackageOption pkgs "cloudflared" { };
tunnels = mkOption {
tunnels = lib.mkOption {
description = ''
Cloudflare tunnels.
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
inherit originRequest;
credentialsFile = mkOption {
type = types.str;
credentialsFile = lib.mkOption {
type = lib.types.str;
description = ''
Credential file.
@ -172,8 +169,8 @@ in
};
warp-routing = {
enabled = mkOption {
type = with types; nullOr bool;
enabled = lib.mkOption {
type = with lib.types; nullOr bool;
default = null;
description = ''
Enable warp routing.
@ -183,8 +180,8 @@ in
};
};
default = mkOption {
type = types.str;
default = lib.mkOption {
type = lib.types.str;
description = ''
Catch-all service if no ingress matches.
@ -193,13 +190,13 @@ in
example = "http_status:404";
};
ingress = mkOption {
type = with types; attrsOf (either str (submodule ({ hostname, ... }: {
ingress = lib.mkOption {
type = with lib.types; attrsOf (either str (submodule ({ hostname, ... }: {
options = {
inherit originRequest;
service = mkOption {
type = with types; nullOr str;
service = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Service to pass the traffic.
@ -209,8 +206,8 @@ in
example = "http://localhost:80, tcp://localhost:8000, unix:/home/production/echo.sock, hello_world or http_status:404";
};
path = mkOption {
type = with types; nullOr str;
path = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Path filter.
@ -251,11 +248,11 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.targets =
mapAttrs'
lib.mapAttrs'
(name: tunnel:
nameValuePair "cloudflared-tunnel-${name}" {
lib.nameValuePair "cloudflared-tunnel-${name}" {
description = "Cloudflare tunnel '${name}' target";
requires = [ "cloudflared-tunnel-${name}.service" ];
after = [ "cloudflared-tunnel-${name}.service" ];
@ -265,41 +262,41 @@ in
config.services.cloudflared.tunnels;
systemd.services =
mapAttrs'
lib.mapAttrs'
(name: tunnel:
let
filterConfig = lib.attrsets.filterAttrsRecursive (_: v: ! builtins.elem v [ null [ ] { } ]);
filterIngressSet = filterAttrs (_: v: builtins.typeOf v == "set");
filterIngressStr = filterAttrs (_: v: builtins.typeOf v == "string");
filterIngressSet = lib.filterAttrs (_: v: builtins.typeOf v == "set");
filterIngressStr = lib.filterAttrs (_: v: builtins.typeOf v == "string");
ingressesSet = filterIngressSet tunnel.ingress;
ingressesStr = filterIngressStr tunnel.ingress;
fullConfig = filterConfig {
fullConfig = lib.filterConfig {
tunnel = name;
"credentials-file" = tunnel.credentialsFile;
warp-routing = filterConfig tunnel.warp-routing;
originRequest = filterConfig tunnel.originRequest;
warp-routing = lib.filterConfig tunnel.warp-routing;
originRequest = lib.filterConfig tunnel.originRequest;
ingress =
(map
(key: {
hostname = key;
} // getAttr key (filterConfig (filterConfig ingressesSet)))
(attrNames ingressesSet))
} // lib.getAttr key (filterConfig (filterConfig ingressesSet)))
(lib.attrNames ingressesSet))
++
(map
(key: {
hostname = key;
service = getAttr key ingressesStr;
service = lib.getAttr key ingressesStr;
})
(attrNames ingressesStr))
(lib.attrNames ingressesStr))
++ [{ service = tunnel.default; }];
};
mkConfigFile = pkgs.writeText "cloudflared.yml" (builtins.toJSON fullConfig);
in
nameValuePair "cloudflared-tunnel-${name}" ({
lib.nameValuePair "cloudflared-tunnel-${name}" ({
after = [ "network.target" "network-online.target" ];
wants = [ "network.target" "network-online.target" ];
wantedBy = [ "multi-user.target" ];
@ -313,17 +310,17 @@ in
)
config.services.cloudflared.tunnels;
users.users = mkIf (cfg.user == "cloudflared") {
users.users = lib.mkIf (cfg.user == "cloudflared") {
cloudflared = {
group = cfg.group;
isSystemUser = true;
};
};
users.groups = mkIf (cfg.group == "cloudflared") {
users.groups = lib.mkIf (cfg.group == "cloudflared") {
cloudflared = { };
};
};
meta.maintainers = with maintainers; [ bbigras anpin ];
meta.maintainers = with lib.maintainers; [ bbigras anpin ];
}

View File

@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.cntlm;
@ -16,11 +13,11 @@ let
Username ${cfg.username}
Domain ${cfg.domain}
Password ${cfg.password}
${optionalString (cfg.netbios_hostname != "") "Workstation ${cfg.netbios_hostname}"}
${concatMapStrings (entry: "Proxy ${entry}\n") cfg.proxy}
${optionalString (cfg.noproxy != []) "NoProxy ${concatStringsSep ", " cfg.noproxy}"}
${lib.optionalString (cfg.netbios_hostname != "") "Workstation ${cfg.netbios_hostname}"}
${lib.concatMapStrings (entry: "Proxy ${entry}\n") cfg.proxy}
${lib.optionalString (cfg.noproxy != []) "NoProxy ${lib.concatStringsSep ", " cfg.noproxy}"}
${concatMapStrings (port: ''
${lib.concatMapStrings (port: ''
Listen ${toString port}
'') cfg.port}
@ -33,36 +30,36 @@ in
options.services.cntlm = {
enable = mkEnableOption "cntlm, which starts a local proxy";
enable = lib.mkEnableOption "cntlm, which starts a local proxy";
username = mkOption {
type = types.str;
username = lib.mkOption {
type = lib.types.str;
description = ''
Proxy account name, without the possibility to include domain name ('at' sign is interpreted literally).
'';
};
domain = mkOption {
type = types.str;
domain = lib.mkOption {
type = lib.types.str;
description = "Proxy account domain/workgroup name.";
};
password = mkOption {
password = lib.mkOption {
default = "/etc/cntlm.password";
type = types.str;
type = lib.types.str;
description = "Proxy account password. Note: use chmod 0600 on /etc/cntlm.password for security.";
};
netbios_hostname = mkOption {
type = types.str;
netbios_hostname = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
The hostname of your machine.
'';
};
proxy = mkOption {
type = types.listOf types.str;
proxy = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
A list of NTLM/NTLMv2 authenticating HTTP proxies.
@ -73,29 +70,29 @@ in
example = [ "proxy.example.com:81" ];
};
noproxy = mkOption {
noproxy = lib.mkOption {
description = ''
A list of domains where the proxy is skipped.
'';
default = [];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
example = [ "*.example.com" "example.com" ];
};
port = mkOption {
port = lib.mkOption {
default = [3128];
type = types.listOf types.port;
type = lib.types.listOf lib.types.port;
description = "Specifies on which ports the cntlm daemon listens.";
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Additional config appended to the end of the generated {file}`cntlm.conf`.";
};
configText = mkOption {
type = types.lines;
configText = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Verbatim contents of {file}`cntlm.conf`.";
};
@ -104,7 +101,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.cntlm = {
description = "CNTLM is an NTLM / NTLM Session Response / NTLMv2 authenticating HTTP proxy";
after = [ "network.target" ];

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
dataDir = "/var/lib/consul";
@ -16,8 +14,8 @@ let
configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ]
++ cfg.extraConfigFiles;
devices = attrValues (filterAttrs (_: i: i != null) cfg.interface);
systemdDevices = forEach devices
devices = lib.attrValues (lib.filterAttrs (_: i: i != null) cfg.interface);
systemdDevices = lib.forEach devices
(i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device");
in
{
@ -25,26 +23,26 @@ in
services.consul = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Enables the consul daemon.
'';
};
package = mkPackageOption pkgs "consul" { };
package = lib.mkPackageOption pkgs "consul" { };
webUi = mkOption {
type = types.bool;
webUi = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Enables the web interface on the consul http port.
'';
};
leaveOnStop = mkOption {
type = types.bool;
leaveOnStop = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
If enabled, causes a leave action to be sent when closing consul.
@ -57,16 +55,16 @@ in
interface = {
advertise = mkOption {
type = types.nullOr types.str;
advertise = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The name of the interface to pull the advertise_addr from.
'';
};
bind = mkOption {
type = types.nullOr types.str;
bind = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The name of the interface to pull the bind_addr from.
@ -74,16 +72,16 @@ in
};
};
forceAddrFamily = mkOption {
type = types.enum [ "any" "ipv4" "ipv6" ];
forceAddrFamily = lib.mkOption {
type = lib.types.enum [ "any" "ipv4" "ipv6" ];
default = "any";
description = ''
Whether to bind ipv4/ipv6 or both kind of addresses.
'';
};
forceIpv4 = mkOption {
type = types.nullOr types.bool;
forceIpv4 = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Deprecated: Use consul.forceAddrFamily instead.
@ -91,26 +89,26 @@ in
'';
};
dropPrivileges = mkOption {
type = types.bool;
dropPrivileges = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether the consul agent should be run as a non-root consul user.
'';
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = { };
type = types.attrsOf types.anything;
type = lib.types.attrsOf lib.types.anything;
description = ''
Extra configuration options which are serialized to json and added
to the config.json file.
'';
};
extraConfigFiles = mkOption {
extraConfigFiles = lib.mkOption {
default = [ ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Additional configuration files to pass to consul
NOTE: These will not trigger the service to be restarted when altered.
@ -118,32 +116,32 @@ in
};
alerts = {
enable = mkEnableOption "consul-alerts";
enable = lib.mkEnableOption "consul-alerts";
package = mkPackageOption pkgs "consul-alerts" { };
package = lib.mkPackageOption pkgs "consul-alerts" { };
listenAddr = mkOption {
listenAddr = lib.mkOption {
description = "Api listening address.";
default = "localhost:9000";
type = types.str;
type = lib.types.str;
};
consulAddr = mkOption {
consulAddr = lib.mkOption {
description = "Consul api listening address";
default = "localhost:8500";
type = types.str;
type = lib.types.str;
};
watchChecks = mkOption {
watchChecks = lib.mkOption {
description = "Whether to enable check watcher.";
default = true;
type = types.bool;
type = lib.types.bool;
};
watchEvents = mkOption {
watchEvents = lib.mkOption {
description = "Whether to enable event watcher.";
default = true;
type = types.bool;
type = lib.types.bool;
};
};
@ -151,8 +149,8 @@ in
};
config = mkIf cfg.enable (
mkMerge [{
config = lib.mkIf cfg.enable (
lib.mkMerge [{
users.users.consul = {
description = "Consul agent daemon user";
@ -182,18 +180,18 @@ in
after = [ "network.target" ] ++ systemdDevices;
bindsTo = systemdDevices;
restartTriggers = [ config.environment.etc."consul.json".source ]
++ mapAttrsToList (_: d: d.source)
(filterAttrs (n: _: hasPrefix "consul.d/" n) config.environment.etc);
++ lib.mapAttrsToList (_: d: d.source)
(lib.filterAttrs (n: _: lib.hasPrefix "consul.d/" n) config.environment.etc);
serviceConfig = {
ExecStart = "@${lib.getExe cfg.package} consul agent -config-dir /etc/consul.d"
+ concatMapStrings (n: " -config-file ${n}") configFiles;
+ lib.concatMapStrings (n: " -config-file ${n}") configFiles;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
PermissionsStartOnly = true;
User = if cfg.dropPrivileges then "consul" else null;
Restart = "on-failure";
TimeoutStartSec = "infinity";
} // (optionalAttrs (cfg.leaveOnStop) {
} // (lib.optionalAttrs (cfg.leaveOnStop) {
ExecStop = "${lib.getExe cfg.package} leave";
});
@ -231,8 +229,8 @@ in
echo "{" > /etc/consul-addrs.json
delim=" "
''
+ concatStrings (flip mapAttrsToList cfg.interface (name: i:
optionalString (i != null) ''
+ lib.concatStrings (lib.flip lib.mapAttrsToList cfg.interface (name: i:
lib.optionalString (i != null) ''
echo "$delim \"${name}_addr\": \"$(getAddr "${i}")\"" >> /etc/consul-addrs.json
delim=","
''))
@ -243,11 +241,11 @@ in
}
# deprecated
(mkIf (cfg.forceIpv4 != null && cfg.forceIpv4) {
(lib.mkIf (cfg.forceIpv4 != null && cfg.forceIpv4) {
services.consul.forceAddrFamily = "ipv4";
})
(mkIf (cfg.alerts.enable) {
(lib.mkIf (cfg.alerts.enable) {
systemd.services.consul-alerts = {
wantedBy = [ "multi-user.target" ];
after = [ "consul.service" ];
@ -259,8 +257,8 @@ in
${lib.getExe cfg.alerts.package} start \
--alert-addr=${cfg.alerts.listenAddr} \
--consul-addr=${cfg.alerts.consulAddr} \
${optionalString cfg.alerts.watchChecks "--watch-checks"} \
${optionalString cfg.alerts.watchEvents "--watch-events"}
${lib.optionalString cfg.alerts.watchChecks "--watch-checks"} \
${lib.optionalString cfg.alerts.watchEvents "--watch-events"}
'';
User = if cfg.dropPrivileges then "consul" else null;
Restart = "on-failure";

View File

@ -1,39 +1,36 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.coredns;
configFile = pkgs.writeText "Corefile" cfg.config;
in {
options.services.coredns = {
enable = mkEnableOption "Coredns dns server";
enable = lib.mkEnableOption "Coredns dns server";
config = mkOption {
config = lib.mkOption {
default = "";
example = ''
. {
whoami
}
'';
type = types.lines;
type = lib.types.lines;
description = ''
Verbatim Corefile to use.
See <https://coredns.io/manual/toc/#configuration> for details.
'';
};
package = mkPackageOption pkgs "coredns" { };
package = lib.mkPackageOption pkgs "coredns" { };
extraArgs = mkOption {
extraArgs = lib.mkOption {
default = [];
example = [ "-dns.port=53" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = "Extra arguments to pass to coredns.";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.coredns = {
description = "Coredns dns server";
after = [ "network.target" ];
@ -46,7 +43,7 @@ in {
AmbientCapabilities = "cap_net_bind_service";
NoNewPrivileges = true;
DynamicUser = true;
ExecStart = "${getBin cfg.package}/bin/coredns -conf=${configFile} ${lib.escapeShellArgs cfg.extraArgs}";
ExecStart = "${lib.getBin cfg.package}/bin/coredns -conf=${configFile} ${lib.escapeShellArgs cfg.extraArgs}";
ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR1 $MAINPID";
Restart = "on-failure";
};

View File

@ -1,20 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.corerad;
settingsFormat = pkgs.formats.toml {};
in {
meta.maintainers = with maintainers; [ mdlayher ];
meta.maintainers = with lib.maintainers; [ mdlayher ];
options.services.corerad = {
enable = mkEnableOption "CoreRAD IPv6 NDP RA daemon";
enable = lib.mkEnableOption "CoreRAD IPv6 NDP RA daemon";
settings = mkOption {
settings = lib.mkOption {
type = settingsFormat.type;
example = literalExpression ''
example = lib.literalExpression ''
{
interfaces = [
# eth0 is an upstream interface monitoring for IPv6 router advertisements.
@ -42,18 +39,18 @@ in {
'';
};
configFile = mkOption {
type = types.path;
example = literalExpression ''"''${pkgs.corerad}/etc/corerad/corerad.toml"'';
configFile = lib.mkOption {
type = lib.types.path;
example = lib.literalExpression ''"''${pkgs.corerad}/etc/corerad/corerad.toml"'';
description = "Path to CoreRAD TOML configuration file.";
};
package = mkPackageOption pkgs "corerad" { };
package = lib.mkPackageOption pkgs "corerad" { };
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
# Prefer the config file over settings if both are set.
services.corerad.configFile = mkDefault (settingsFormat.generate "corerad.toml" cfg.settings);
services.corerad.configFile = lib.mkDefault (settingsFormat.generate "corerad.toml" cfg.settings);
systemd.services.corerad = {
description = "CoreRAD IPv6 NDP RA daemon";
@ -68,7 +65,7 @@ in {
DynamicUser = true;
Type = "notify";
NotifyAccess = "main";
ExecStart = "${getBin cfg.package}/bin/corerad -c=${cfg.configFile}";
ExecStart = "${lib.getBin cfg.package}/bin/corerad -c=${cfg.configFile}";
Restart = "on-failure";
RestartKillSignal = "SIGHUP";
};

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.coturn;
pidfile = "/run/turnserver/turnserver.pid";
@ -8,8 +7,8 @@ listening-port=${toString cfg.listening-port}
tls-listening-port=${toString cfg.tls-listening-port}
alt-listening-port=${toString cfg.alt-listening-port}
alt-tls-listening-port=${toString cfg.alt-tls-listening-port}
${concatStringsSep "\n" (map (x: "listening-ip=${x}") cfg.listening-ips)}
${concatStringsSep "\n" (map (x: "relay-ip=${x}") cfg.relay-ips)}
${lib.concatStringsSep "\n" (map (x: "listening-ip=${x}") cfg.listening-ips)}
${lib.concatStringsSep "\n" (map (x: "relay-ip=${x}") cfg.relay-ips)}
min-port=${toString cfg.min-port}
max-port=${toString cfg.max-port}
${lib.optionalString cfg.lt-cred-mech "lt-cred-mech"}
@ -40,9 +39,9 @@ ${cfg.extraConfig}
in {
options = {
services.coturn = {
enable = mkEnableOption "coturn TURN server";
listening-port = mkOption {
type = types.int;
enable = lib.mkEnableOption "coturn TURN server";
listening-port = lib.mkOption {
type = lib.types.int;
default = 3478;
description = ''
TURN listener port for UDP and TCP.
@ -50,8 +49,8 @@ in {
"plain" TCP and UDP port(s), too - if allowed by configuration.
'';
};
tls-listening-port = mkOption {
type = types.int;
tls-listening-port = lib.mkOption {
type = lib.types.int;
default = 5349;
description = ''
TURN listener port for TLS.
@ -65,10 +64,10 @@ in {
For secure UDP connections, we support DTLS version 1.
'';
};
alt-listening-port = mkOption {
type = types.int;
alt-listening-port = lib.mkOption {
type = lib.types.int;
default = cfg.listening-port + 1;
defaultText = literalExpression "listening-port + 1";
defaultText = lib.literalExpression "listening-port + 1";
description = ''
Alternative listening port for UDP and TCP listeners;
default (or zero) value means "listening port plus one".
@ -80,16 +79,16 @@ in {
are listening to that endpoint only for "symmetry".
'';
};
alt-tls-listening-port = mkOption {
type = types.int;
alt-tls-listening-port = lib.mkOption {
type = lib.types.int;
default = cfg.tls-listening-port + 1;
defaultText = literalExpression "tls-listening-port + 1";
defaultText = lib.literalExpression "tls-listening-port + 1";
description = ''
Alternative listening port for TLS and DTLS protocols.
'';
};
listening-ips = mkOption {
type = types.listOf types.str;
listening-ips = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = [ "203.0.113.42" "2001:DB8::42" ];
description = ''
@ -98,8 +97,8 @@ in {
then all IPv4 and IPv6 system IPs will be used for listening.
'';
};
relay-ips = mkOption {
type = types.listOf types.str;
relay-ips = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = [ "203.0.113.42" "2001:DB8::42" ];
description = ''
@ -115,29 +114,29 @@ in {
as the family of the client socket).
'';
};
min-port = mkOption {
type = types.int;
min-port = lib.mkOption {
type = lib.types.int;
default = 49152;
description = ''
Lower bound of UDP relay endpoints
'';
};
max-port = mkOption {
type = types.int;
max-port = lib.mkOption {
type = lib.types.int;
default = 65535;
description = ''
Upper bound of UDP relay endpoints
'';
};
lt-cred-mech = mkOption {
type = types.bool;
lt-cred-mech = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Use long-term credential mechanism.
'';
};
no-auth = mkOption {
type = types.bool;
no-auth = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
This option is opposite to lt-cred-mech.
@ -148,8 +147,8 @@ in {
lt-cred-mech is default.
'';
};
use-auth-secret = mkOption {
type = types.bool;
use-auth-secret = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
TURN REST API flag.
@ -172,8 +171,8 @@ in {
or can be found in the turn_secret table in the database.
'';
};
static-auth-secret = mkOption {
type = types.nullOr types.str;
static-auth-secret = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
'Static' authentication secret value (a string) for TURN REST API only.
@ -183,17 +182,17 @@ in {
by a separate program, so this is why that other mode is 'dynamic'.
'';
};
static-auth-secret-file = mkOption {
type = types.nullOr types.str;
static-auth-secret-file = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Path to the file containing the static authentication secret.
'';
};
realm = mkOption {
type = types.str;
realm = lib.mkOption {
type = lib.types.str;
default = config.networking.hostName;
defaultText = literalExpression "config.networking.hostName";
defaultText = lib.literalExpression "config.networking.hostName";
example = "example.com";
description = ''
The default realm to be used for the users when no explicit
@ -203,60 +202,60 @@ in {
mechanism or with TURN REST API.
'';
};
cert = mkOption {
type = types.nullOr types.str;
cert = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/var/lib/acme/example.com/fullchain.pem";
description = ''
Certificate file in PEM format.
'';
};
pkey = mkOption {
type = types.nullOr types.str;
pkey = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/var/lib/acme/example.com/key.pem";
description = ''
Private key file in PEM format.
'';
};
dh-file = mkOption {
type = types.nullOr types.str;
dh-file = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Use custom DH TLS key, stored in PEM format in the file.
'';
};
secure-stun = mkOption {
type = types.bool;
secure-stun = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Require authentication of the STUN Binding request.
By default, the clients are allowed anonymous access to the STUN Binding functionality.
'';
};
no-cli = mkOption {
type = types.bool;
no-cli = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Turn OFF the CLI support.
'';
};
cli-ip = mkOption {
type = types.str;
cli-ip = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
Local system IP address to be used for CLI server endpoint.
'';
};
cli-port = mkOption {
type = types.int;
cli-port = lib.mkOption {
type = lib.types.int;
default = 5766;
description = ''
CLI server port.
'';
};
cli-password = mkOption {
type = types.nullOr types.str;
cli-password = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
CLI access password.
@ -264,45 +263,45 @@ in {
for of the password (see the -P command in the turnadmin utility).
'';
};
no-udp = mkOption {
type = types.bool;
no-udp = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable UDP client listener";
};
no-tcp = mkOption {
type = types.bool;
no-tcp = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable TCP client listener";
};
no-tls = mkOption {
type = types.bool;
no-tls = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable TLS client listener";
};
no-dtls = mkOption {
type = types.bool;
no-dtls = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable DTLS client listener";
};
no-udp-relay = mkOption {
type = types.bool;
no-udp-relay = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable UDP relay endpoints";
};
no-tcp-relay = mkOption {
type = types.bool;
no-tcp-relay = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Disable TCP relay endpoints";
};
extraConfig = mkOption {
type = types.lines;
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Additional configuration options";
};
};
};
config = mkIf cfg.enable (mkMerge ([
config = lib.mkIf cfg.enable (lib.mkMerge ([
{ assertions = [
{ assertion = cfg.static-auth-secret != null -> cfg.static-auth-secret-file == null ;
message = "static-auth-secret and static-auth-secret-file cannot be set at the same time";
@ -334,7 +333,7 @@ in {
preStart = ''
cat ${configFile} > ${runConfig}
${optionalString (cfg.static-auth-secret-file != null) ''
${lib.optionalString (cfg.static-auth-secret-file != null) ''
${pkgs.replace-secret}/bin/replace-secret \
"#static-auth-secret#" \
${cfg.static-auth-secret-file} \
@ -349,7 +348,7 @@ in {
User = "turnserver";
Group = "turnserver";
AmbientCapabilities =
mkIf (
lib.mkIf (
cfg.listening-port < 1024 ||
cfg.alt-listening-port < 1024 ||
cfg.tls-listening-port < 1024 ||

View File

@ -1,16 +1,13 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.create_ap;
configFile = pkgs.writeText "create_ap.conf" (generators.toKeyValue { } cfg.settings);
configFile = pkgs.writeText "create_ap.conf" (lib.generators.toKeyValue { } cfg.settings);
in {
options = {
services.create_ap = {
enable = mkEnableOption "setting up wifi hotspots using create_ap";
settings = mkOption {
type = with types; attrsOf (oneOf [ int bool str ]);
enable = lib.mkEnableOption "setting up wifi hotspots using create_ap";
settings = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ int bool str ]);
default = {};
description = ''
Configuration for `create_ap`.
@ -27,7 +24,7 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd = {
services.create_ap = {

View File

@ -1,6 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.dante;
confFile = pkgs.writeText "dante-sockd.conf" ''
@ -14,15 +12,15 @@ in
{
meta = {
maintainers = with maintainers; [ arobyn ];
maintainers = with lib.maintainers; [ arobyn ];
};
options = {
services.dante = {
enable = mkEnableOption "Dante SOCKS proxy";
enable = lib.mkEnableOption "Dante SOCKS proxy";
config = mkOption {
type = types.lines;
config = lib.mkOption {
type = lib.types.lines;
description = ''
Contents of Dante's configuration file.
NOTE: user.privileged, user.unprivileged and logoutput are set by the service.
@ -31,7 +29,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{ assertion = cfg.config != "";
message = "please provide Dante configuration file contents";

View File

@ -1,5 +1,4 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.ddclient;
boolToStr = bool: if bool then "yes" else "no";
@ -39,21 +38,17 @@ let
sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf
'')}
'';
in
with lib;
{
imports = [
(mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
(lib.mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
(config:
let value = getAttrFromPath [ "services" "ddclient" "domain" ] config;
in optional (value != "") value))
(mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
(mkRemovedOptionModule [ "services" "ddclient" "password" ] "Use services.ddclient.passwordFile instead.")
(mkRemovedOptionModule [ "services" "ddclient" "ipv6" ] "")
let value = lib.getAttrFromPath [ "services" "ddclient" "domain" ] config;
in lib.optional (value != "") value))
(lib.mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
(lib.mkRemovedOptionModule [ "services" "ddclient" "password" ] "Use services.ddclient.passwordFile instead.")
(lib.mkRemovedOptionModule [ "services" "ddclient" "ipv6" ] "")
];
###### interface
@ -62,7 +57,7 @@ with lib;
services.ddclient = with lib.types; {
enable = mkOption {
enable = lib.mkOption {
default = false;
type = bool;
description = ''
@ -70,7 +65,7 @@ with lib;
'';
};
package = mkOption {
package = lib.mkOption {
type = package;
default = pkgs.ddclient;
defaultText = lib.literalExpression "pkgs.ddclient";
@ -79,7 +74,7 @@ with lib;
'';
};
domains = mkOption {
domains = lib.mkOption {
default = [ "" ];
type = listOf str;
description = ''
@ -87,7 +82,7 @@ with lib;
'';
};
username = mkOption {
username = lib.mkOption {
# For `nsupdate` username contains the path to the nsupdate executable
default = lib.optionalString (config.services.ddclient.protocol == "nsupdate") "${pkgs.bind.dnsutils}/bin/nsupdate";
defaultText = "";
@ -97,7 +92,7 @@ with lib;
'';
};
passwordFile = mkOption {
passwordFile = lib.mkOption {
default = null;
type = nullOr str;
description = ''
@ -105,7 +100,7 @@ with lib;
'';
};
interval = mkOption {
interval = lib.mkOption {
default = "10min";
type = str;
description = ''
@ -114,7 +109,7 @@ with lib;
'';
};
configFile = mkOption {
configFile = lib.mkOption {
default = null;
type = nullOr path;
description = ''
@ -124,7 +119,7 @@ with lib;
example = "/root/nixos/secrets/ddclient.conf";
};
protocol = mkOption {
protocol = lib.mkOption {
default = "dyndns2";
type = str;
description = ''
@ -132,7 +127,7 @@ with lib;
'';
};
server = mkOption {
server = lib.mkOption {
default = "";
type = str;
description = ''
@ -140,7 +135,7 @@ with lib;
'';
};
ssl = mkOption {
ssl = lib.mkOption {
default = true;
type = bool;
description = ''
@ -148,7 +143,7 @@ with lib;
'';
};
quiet = mkOption {
quiet = lib.mkOption {
default = false;
type = bool;
description = ''
@ -156,7 +151,7 @@ with lib;
'';
};
script = mkOption {
script = lib.mkOption {
default = "";
type = str;
description = ''
@ -164,21 +159,21 @@ with lib;
'';
};
use = mkOption {
use = lib.mkOption {
default = "";
type = str;
description = ''
Method to determine the IP address to send to the dynamic DNS provider.
'';
};
usev4 = mkOption {
usev4 = lib.mkOption {
default = "webv4, webv4=checkip.dyndns.com/, webv4-skip='Current IP Address: '";
type = str;
description = ''
Method to determine the IPv4 address to send to the dynamic DNS provider. Only used if `use` is not set.
'';
};
usev6 = mkOption {
usev6 = lib.mkOption {
default = "webv6, webv6=checkipv6.dyndns.com/, webv6-skip='Current IP Address: '";
type = str;
description = ''
@ -186,7 +181,7 @@ with lib;
'';
};
verbose = mkOption {
verbose = lib.mkOption {
default = false;
type = bool;
description = ''
@ -194,7 +189,7 @@ with lib;
'';
};
zone = mkOption {
zone = lib.mkOption {
default = "";
type = str;
description = ''
@ -202,7 +197,7 @@ with lib;
'';
};
extraConfig = mkOption {
extraConfig = lib.mkOption {
default = "";
type = lines;
description = ''
@ -219,14 +214,14 @@ with lib;
###### implementation
config = mkIf config.services.ddclient.enable {
config = lib.mkIf config.services.ddclient.enable {
warnings = lib.optional (cfg.use != "") "Setting `use` is deprecated, ddclient now supports `usev4` and `usev6` for separate IPv4/IPv6 configuration.";
systemd.services.ddclient = {
description = "Dynamic DNS Client";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
restartTriggers = optional (cfg.configFile != null) cfg.configFile;
restartTriggers = lib.optional (cfg.configFile != null) cfg.configFile;
path = lib.optional (lib.hasPrefix "if," cfg.use) pkgs.iproute2;
serviceConfig = {

Some files were not shown because too many files have changed in this diff Show More