diff options
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/misc/ids.nix | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh-syntax-highlighting.nix | 37 | ||||
-rw-r--r-- | nixos/modules/security/acme.nix | 64 | ||||
-rw-r--r-- | nixos/modules/services/mail/spamassassin.nix | 164 | ||||
-rw-r--r-- | nixos/modules/services/network-filesystems/glusterfs.nix | 5 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnschain.nix | 16 | ||||
-rw-r--r-- | nixos/modules/services/networking/i2pd.nix | 3 | ||||
-rw-r--r-- | nixos/modules/services/networking/networkmanager.nix | 21 | ||||
-rw-r--r-- | nixos/modules/services/networking/resilio.nix | 268 | ||||
-rw-r--r-- | nixos/modules/services/x11/window-managers/qtile.nix | 2 |
11 files changed, 516 insertions, 67 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index d217b3452fb5..d7459e3fe91c 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -294,6 +294,7 @@ jackett = 276; aria2 = 277; clickhouse = 278; + rslsync = 279; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -557,6 +558,7 @@ jackett = 276; aria2 = 277; clickhouse = 278; + rslsync = 279; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 7afcb9051bd7..47adfa334eed 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -485,6 +485,7 @@ ./services/networking/radvd.nix ./services/networking/rdnssd.nix ./services/networking/redsocks.nix + ./services/networking/resilio.nix ./services/networking/rpcbind.nix ./services/networking/sabnzbd.nix ./services/networking/searx.nix diff --git a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix index 39176b287843..9452489e2fb4 100644 --- a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix +++ b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix @@ -8,13 +8,7 @@ in { options = { programs.zsh.syntaxHighlighting = { - enable = mkOption { - default = false; - type = types.bool; - description = '' - Enable zsh-syntax-highlighting. - ''; - }; + enable = mkEnableOption "zsh-syntax-highlighting"; highlighters = mkOption { default = [ "main" ]; @@ -38,13 +32,13 @@ in }; patterns = mkOption { - default = []; - type = types.listOf(types.listOf(types.string)); + default = {}; + type = types.attrsOf types.string; example = literalExample '' - [ - ["rm -rf *" "fg=white,bold,bg=red"] - ] + { + "rm -rf *" = "fg=white,bold,bg=red"; + } ''; description = '' @@ -67,14 +61,17 @@ in "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})" } - ${optionalString (length(cfg.patterns) > 0) - (assert(elem "pattern" cfg.highlighters); (foldl ( - a: b: - assert(length(b) == 2); '' - ${a} - ZSH_HIGHLIGHT_PATTERNS+=('${elemAt b 0}' '${elemAt b 1}') - '' - ) "") cfg.patterns) + ${let + n = attrNames cfg.patterns; + in + optionalString (length(n) > 0) + (assert(elem "pattern" cfg.highlighters); (foldl ( + a: b: + '' + ${a} + ZSH_HIGHLIGHT_PATTERNS+=('${b}' '${attrByPath [b] "" cfg.patterns}') + '' + ) "") n) } ''; }; diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix index 321b9f7f3753..a40c5ef9ebe1 100644 --- a/nixos/modules/security/acme.nix +++ b/nixos/modules/security/acme.nix @@ -13,7 +13,7 @@ let description = '' Where the webroot of the HTTP vhost is located. <filename>.well-known/acme-challenge/</filename> directory - will be created automatically if it doesn't exist. + will be created below the webroot if it doesn't exist. <literal>http://example.org/.well-known/acme-challenge/</literal> must also be available (notice unencrypted HTTP). ''; @@ -46,7 +46,10 @@ let allowKeysForGroup = mkOption { type = types.bool; default = false; - description = "Give read permissions to the specified group to read SSL private certificates."; + description = '' + Give read permissions to the specified group + (<option>security.acme.group</option>) to read SSL private certificates. + ''; }; postRun = mkOption { @@ -65,21 +68,24 @@ let "cert.der" "cert.pem" "chain.pem" "external.sh" "fullchain.pem" "full.pem" "key.der" "key.pem" "account_key.json" ]); - default = [ "fullchain.pem" "key.pem" "account_key.json" ]; + default = [ "fullchain.pem" "full.pem" "key.pem" "account_key.json" ]; description = '' Plugins to enable. With default settings simp_le will - store public certificate bundle in <filename>fullchain.pem</filename> - and private key in <filename>key.pem</filename> in its state directory. + store public certificate bundle in <filename>fullchain.pem</filename>, + private key in <filename>key.pem</filename> and those two previous + files combined in <filename>full.pem</filename> in its state directory. ''; }; extraDomains = mkOption { type = types.attrsOf (types.nullOr types.str); default = {}; - example = { - "example.org" = "/srv/http/nginx"; - "mydomain.org" = null; - }; + example = literalExample '' + { + "example.org" = "/srv/http/nginx"; + "mydomain.org" = null; + } + ''; description = '' Extra domain names for which certificates are to be issued, with their own server roots if needed. @@ -139,17 +145,19 @@ in description = '' Attribute set of certificates to get signed and renewed. ''; - example = { - "example.com" = { - webroot = "/var/www/challenges/"; - email = "foo@example.com"; - extraDomains = { "www.example.com" = null; "foo.example.com" = "/var/www/foo/"; }; - }; - "bar.example.com" = { - webroot = "/var/www/challenges/"; - email = "bar@example.com"; - }; - }; + example = literalExample '' + { + "example.com" = { + webroot = "/var/www/challenges/"; + email = "foo@example.com"; + extraDomains = { "www.example.com" = null; "foo.example.com" = "/var/www/foo/"; }; + }; + "bar.example.com" = { + webroot = "/var/www/challenges/"; + email = "bar@example.com"; + }; + } + ''; }; }; }; @@ -238,6 +246,9 @@ in mv $workdir/server.key ${cpath}/key.pem mv $workdir/server.crt ${cpath}/fullchain.pem + # Create full.pem for e.g. lighttpd (same format as "simp_le ... -f full.pem" creates) + cat "${cpath}/key.pem" "${cpath}/fullchain.pem" > "${cpath}/full.pem" + # Clean up working directory rm $workdir/server.csr rm $workdir/server.pass.key @@ -247,6 +258,8 @@ in chown '${data.user}:${data.group}' '${cpath}/key.pem' chmod ${rights} '${cpath}/fullchain.pem' chown '${data.user}:${data.group}' '${cpath}/fullchain.pem' + chmod ${rights} '${cpath}/full.pem' + chown '${data.user}:${data.group}' '${cpath}/full.pem' ''; serviceConfig = { Type = "oneshot"; @@ -275,15 +288,14 @@ in ) ); servicesAttr = listToAttrs services; - nginxAttr = { - nginx = { - after = [ "acme-selfsigned-certificates.target" ]; - wants = [ "acme-selfsigned-certificates.target" "acme-certificates.target" ]; - }; + injectServiceDep = { + after = [ "acme-selfsigned-certificates.target" ]; + wants = [ "acme-selfsigned-certificates.target" "acme-certificates.target" ]; }; in servicesAttr // - (if config.services.nginx.enable then nginxAttr else {}); + (if config.services.nginx.enable then { nginx = injectServiceDep; } else {}) // + (if config.services.lighttpd.enable then { lighttpd = injectServiceDep; } else {}); systemd.timers = flip mapAttrs' cfg.certs (cert: data: nameValuePair ("acme-${cert}") diff --git a/nixos/modules/services/mail/spamassassin.nix b/nixos/modules/services/mail/spamassassin.nix index 08953134b3b3..fc8396cd85e9 100644 --- a/nixos/modules/services/mail/spamassassin.nix +++ b/nixos/modules/services/mail/spamassassin.nix @@ -3,43 +3,129 @@ with lib; let - cfg = config.services.spamassassin; + spamassassin-local-cf = pkgs.writeText "local.cf" cfg.config; + spamassassin-init-pre = pkgs.writeText "init.pre" cfg.initPreConf; + + spamdEnv = pkgs.buildEnv { + name = "spamd-env"; + paths = []; + postBuild = '' + ln -sf ${spamassassin-init-pre} $out/init.pre + ln -sf ${spamassassin-local-cf} $out/local.cf + ''; + }; in { - - ###### interface - options = { services.spamassassin = { - enable = mkOption { default = false; - description = "Whether to run the SpamAssassin daemon."; + description = "Whether to run the SpamAssassin daemon"; }; debug = mkOption { default = false; - description = "Whether to run the SpamAssassin daemon in debug mode."; + description = "Whether to run the SpamAssassin daemon in debug mode"; }; - }; + config = mkOption { + type = types.lines; + description = '' + The SpamAssassin local.cf config + + If you are using this configuration: + add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_ + + Then you can Use this sieve filter: + require ["fileinto", "reject", "envelope"]; + + if header :contains "X-Spam-Flag" "YES" { + fileinto "spam"; + } + + Or this procmail filter: + :0: + * ^X-Spam-Flag: YES + /var/vpopmail/domains/lastlog.de/js/.maildir/.spam/new + + To filter your messages based on the additional mail headers added by spamassassin. + ''; + example = '' + #rewrite_header Subject [***** SPAM _SCORE_ *****] + required_score 5.0 + use_bayes 1 + bayes_auto_learn 1 + add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_ + ''; + default = ""; + }; + initPreConf = mkOption { + type = types.str; + description = "The SpamAssassin init.pre config."; + default = + '' + # + # to update this list, run this command in the rules directory: + # grep 'loadplugin.*Mail::SpamAssassin::Plugin::.*' -o -h * | sort | uniq + # + + #loadplugin Mail::SpamAssassin::Plugin::AccessDB + #loadplugin Mail::SpamAssassin::Plugin::AntiVirus + loadplugin Mail::SpamAssassin::Plugin::AskDNS + # loadplugin Mail::SpamAssassin::Plugin::ASN + loadplugin Mail::SpamAssassin::Plugin::AutoLearnThreshold + #loadplugin Mail::SpamAssassin::Plugin::AWL + loadplugin Mail::SpamAssassin::Plugin::Bayes + loadplugin Mail::SpamAssassin::Plugin::BodyEval + loadplugin Mail::SpamAssassin::Plugin::Check + #loadplugin Mail::SpamAssassin::Plugin::DCC + loadplugin Mail::SpamAssassin::Plugin::DKIM + loadplugin Mail::SpamAssassin::Plugin::DNSEval + loadplugin Mail::SpamAssassin::Plugin::FreeMail + loadplugin Mail::SpamAssassin::Plugin::Hashcash + loadplugin Mail::SpamAssassin::Plugin::HeaderEval + loadplugin Mail::SpamAssassin::Plugin::HTMLEval + loadplugin Mail::SpamAssassin::Plugin::HTTPSMismatch + loadplugin Mail::SpamAssassin::Plugin::ImageInfo + loadplugin Mail::SpamAssassin::Plugin::MIMEEval + loadplugin Mail::SpamAssassin::Plugin::MIMEHeader + # loadplugin Mail::SpamAssassin::Plugin::PDFInfo + #loadplugin Mail::SpamAssassin::Plugin::PhishTag + loadplugin Mail::SpamAssassin::Plugin::Pyzor + loadplugin Mail::SpamAssassin::Plugin::Razor2 + # loadplugin Mail::SpamAssassin::Plugin::RelayCountry + loadplugin Mail::SpamAssassin::Plugin::RelayEval + loadplugin Mail::SpamAssassin::Plugin::ReplaceTags + # loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody + # loadplugin Mail::SpamAssassin::Plugin::Shortcircuit + loadplugin Mail::SpamAssassin::Plugin::SpamCop + loadplugin Mail::SpamAssassin::Plugin::SPF + #loadplugin Mail::SpamAssassin::Plugin::TextCat + # loadplugin Mail::SpamAssassin::Plugin::TxRep + loadplugin Mail::SpamAssassin::Plugin::URIDetail + loadplugin Mail::SpamAssassin::Plugin::URIDNSBL + loadplugin Mail::SpamAssassin::Plugin::URIEval + # loadplugin Mail::SpamAssassin::Plugin::URILocalBL + loadplugin Mail::SpamAssassin::Plugin::VBounce + loadplugin Mail::SpamAssassin::Plugin::WhiteListSubject + loadplugin Mail::SpamAssassin::Plugin::WLBLEval + ''; + }; + }; }; - - ###### implementation - config = mkIf cfg.enable { # Allow users to run 'spamc'. environment.systemPackages = [ pkgs.spamassassin ]; users.extraUsers = singleton { - name = "spamd"; + name = "spamd"; description = "Spam Assassin Daemon"; uid = config.ids.uids.spamd; group = "spamd"; @@ -50,13 +136,65 @@ in gid = config.ids.gids.spamd; }; + systemd.services.sa-update = { + script = '' + set +e + ${pkgs.su}/bin/su -s "${pkgs.bash}/bin/bash" -c "${pkgs.spamassassin}/bin/sa-update --gpghomedir=/var/lib/spamassassin/sa-update-keys/ --siteconfigpath=${spamdEnv}/" spamd + + v=$? + set -e + if [ $v -gt 1 ]; then + echo "sa-update execution error" + exit $v + fi + if [ $v -eq 0 ]; then + systemctl reload spamd.service + fi + ''; + }; + + systemd.timers.sa-update = { + description = "sa-update-service"; + partOf = [ "sa-update.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "1:*"; + Persistent = true; + }; + }; + systemd.services.spamd = { description = "Spam Assassin Server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - script = "${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --nouser-config --virtual-config-dir=/var/lib/spamassassin/user-%u --allow-tell --pidfile=/var/run/spamd.pid"; + serviceConfig = { + ExecStart = "${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --siteconfigpath=${spamdEnv} --virtual-config-dir=/var/lib/spamassassin/user-%u --allow-tell --pidfile=/var/run/spamd.pid"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + + # 0 and 1 no error, exitcode > 1 means error: + # https://spamassassin.apache.org/full/3.1.x/doc/sa-update.html#exit_codes + preStart = '' + # this abstraction requires no centralized config at all + if [ -d /etc/spamassassin ]; then + echo "This spamassassin does not support global '/etc/spamassassin' folder for configuration as this would be impure. Merge your configs into 'services.spamassassin' and remove the '/etc/spamassassin' folder to make this service work. Also see 'https://github.com/NixOS/nixpkgs/pull/26470'."; + exit 1 + fi + echo "Recreating '/var/lib/spamasassin' with creating '3.004001' (or similar) and 'sa-update-keys'" + mkdir -p /var/lib/spamassassin + chown spamd:spamd /var/lib/spamassassin -R + set +e + ${pkgs.su}/bin/su -s "${pkgs.bash}/bin/bash" -c "${pkgs.spamassassin}/bin/sa-update --gpghomedir=/var/lib/spamassassin/sa-update-keys/ --siteconfigpath=${spamdEnv}/" spamd + v=$? + set -e + if [ $v -gt 1 ]; then + echo "sa-update execution error" + exit $v + fi + chown spamd:spamd /var/lib/spamassassin -R + ''; }; }; } diff --git a/nixos/modules/services/network-filesystems/glusterfs.nix b/nixos/modules/services/network-filesystems/glusterfs.nix index a2f2c0339515..f7fed793066a 100644 --- a/nixos/modules/services/network-filesystems/glusterfs.nix +++ b/nixos/modules/services/network-filesystems/glusterfs.nix @@ -3,7 +3,7 @@ with lib; let - inherit (pkgs) glusterfs; + inherit (pkgs) glusterfs rsync; cfg = config.services.glusterfs; @@ -50,8 +50,11 @@ in after = [ "rpcbind.service" "network.target" "local-fs.target" ]; before = [ "network-online.target" ]; + # The copying of hooks is due to upstream bug https://bugzilla.redhat.com/show_bug.cgi?id=1452761 preStart = '' install -m 0755 -d /var/log/glusterfs + mkdir -p /var/lib/glusterd/hooks/ + ${rsync}/bin/rsync -a ${glusterfs}/var/lib/glusterd/hooks/ /var/lib/glusterd/hooks/ ''; serviceConfig = { diff --git a/nixos/modules/services/networking/dnschain.nix b/nixos/modules/services/networking/dnschain.nix index b64929960576..ab7bbb15ad4f 100644 --- a/nixos/modules/services/networking/dnschain.nix +++ b/nixos/modules/services/networking/dnschain.nix @@ -17,7 +17,7 @@ let host = ${cfg.dns.address} port = ${toString cfg.dns.port} oldDNSMethod = NO_OLD_DNS - externalIP = ${cfg.dns.address} + externalIP = ${cfg.dns.externalAddress} [http] host = ${cfg.api.hostname} @@ -47,8 +47,18 @@ in type = types.str; default = "127.0.0.1"; description = '' - The IP address that will be used to reach this machine. - Leave this unchanged if you do not wish to directly expose the DNSChain resolver. + The IP address the DNSChain resolver will bind to. + Leave this unchanged if you do not wish to directly expose the resolver. + ''; + }; + + dns.externalAddress = mkOption { + type = types.str; + default = cfg.dns.address; + description = '' + The IP address used by clients to reach the resolver and the value of + the <literal>namecoin.dns</literal> record. Set this in case the bind address + is not the actual IP address (e.g. the machine is behind a NAT). ''; }; diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index 4e176353fc28..7622f030f832 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -212,7 +212,8 @@ in type = with types; nullOr int; default = null; description = '' - Set a router bandwidth limit integer in kbps or letters: L (32), O (256), P (2048), X (>9000) + Set a router bandwidth limit integer in KBps. + If not set, i2pd defaults to 32KBps. ''; }; diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 876dbe1524e4..f8b7f26f5f2f 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -12,6 +12,7 @@ let configFile = writeText "NetworkManager.conf" '' [main] plugins=keyfile + dhcp=${cfg.dhcp} dns=${if cfg.useDnsmasq then "dnsmasq" else "default"} [keyfile] @@ -21,7 +22,7 @@ let ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''} [logging] - level=WARN + level=${cfg.logLevel} [connection] ipv6.ip6-privacy=2 @@ -138,6 +139,22 @@ in { apply = list: (attrValues cfg.basePackages) ++ list; }; + dhcp = mkOption { + type = types.enum [ "dhclient" "dhcpcd" "internal" ]; + default = "dhclient"; + description = '' + Which program (or internal library) should be used for DHCP. + ''; + }; + + logLevel = mkOption { + type = types.enum [ "OFF" "ERR" "WARN" "INFO" "DEBUG" "TRACE" ]; + default = "WARN"; + description = '' + Set the default logging verbosity level. + ''; + }; + appendNameservers = mkOption { type = types.listOf types.str; default = []; @@ -181,7 +198,7 @@ in { }; type = mkOption { - type = types.enum (attrNames dispatcherTypesSubdirMap); + type = types.enum (attrNames dispatcherTypesSubdirMap); default = "basic"; description = '' Dispatcher hook type. Only basic hooks are currently available. diff --git a/nixos/modules/services/networking/resilio.nix b/nixos/modules/services/networking/resilio.nix new file mode 100644 index 000000000000..6d2b7bdbca1b --- /dev/null +++ b/nixos/modules/services/networking/resilio.nix @@ -0,0 +1,268 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.resilio; + + resilioSync = pkgs.resilio-sync; + + sharedFoldersRecord = map (entry: { + secret = entry.secret; + dir = entry.directory; + + use_relay_server = entry.useRelayServer; + use_tracker = entry.useTracker; + use_dht = entry.useDHT; + + search_lan = entry.searchLAN; + use_sync_trash = entry.useSyncTrash; + known_hosts = knownHosts; + }) cfg.sharedFolders; + + configFile = pkgs.writeText "config.json" (builtins.toJSON ({ + device_name = cfg.deviceName; + storage_path = cfg.storagePath; + listening_port = cfg.listeningPort; + use_gui = false; + check_for_updates = cfg.checkForUpdates; + use_upnp = cfg.useUpnp; + download_limit = cfg.downloadLimit; + upload_limit = cfg.uploadLimit; + lan_encrypt_data = cfg.encryptLAN; + } // optionalAttrs cfg.enableWebUI { + webui = { listen = "${cfg.httpListenAddr}:${toString cfg.httpListenPort}"; } // + (optionalAttrs (cfg.httpLogin != "") { login = cfg.httpLogin; }) // + (optionalAttrs (cfg.httpPass != "") { password = cfg.httpPass; }) // + (optionalAttrs (cfg.apiKey != "") { api_key = cfg.apiKey; }) // + (optionalAttrs (cfg.directoryRoot != "") { directory_root = cfg.directoryRoot; }); + } // optionalAttrs (sharedFoldersRecord != []) { + shared_folders = sharedFoldersRecord; + })); + +in +{ + options = { + services.resilio = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, start the Resilio Sync daemon. Once enabled, you can + interact with the service through the Web UI, or configure it in your + NixOS configuration. Enabling the <literal>resilio</literal> service + also installs a systemd user unit which can be used to start + user-specific copies of the daemon. Once installed, you can use + <literal>systemctl --user start resilio</literal> as your user to start + the daemon using the configuration file located at + <literal>$HOME/.config/resilio-sync/config.json</literal>. + ''; + }; + + deviceName = mkOption { + type = types.str; + example = "Voltron"; + default = config.networking.hostName; + description = '' + Name of the Resilio Sync device. + ''; + }; + + listeningPort = mkOption { + type = types.int; + default = 0; + example = 44444; + description = '' + Listening port. Defaults to 0 which randomizes the port. + ''; + }; + + checkForUpdates = mkOption { + type = types.bool; + default = true; + description = '' + Determines whether to check for updates and alert the user + about them in the UI. + ''; + }; + + useUpnp = mkOption { + type = types.bool; + default = true; + description = '' + Use Universal Plug-n-Play (UPnP) + ''; + }; + + downloadLimit = mkOption { + type = types.int; + default = 0; + example = 1024; + description = '' + Download speed limit. 0 is unlimited (default). + ''; + }; + + uploadLimit = mkOption { + type = types.int; + default = 0; + example = 1024; + description = '' + Upload speed limit. 0 is unlimited (default). + ''; + }; + + httpListenAddr = mkOption { + type = types.str; + default = "0.0.0.0"; + example = "1.2.3.4"; + description = '' + HTTP address to bind to. + ''; + }; + + httpListenPort = mkOption { + type = types.int; + default = 9000; + description = '' + HTTP port to bind on. + ''; + }; + + httpLogin = mkOption { + type = types.str; + example = "allyourbase"; + default = ""; + description = '' + HTTP web login username. + ''; + }; + + httpPass = mkOption { + type = types.str; + example = "arebelongtous"; + default = ""; + description = '' + HTTP web login password. + ''; + }; + + encryptLAN = mkOption { + type = types.bool; + default = true; + description = "Encrypt LAN data."; + }; + + enableWebUI = mkOption { + type = types.bool; + default = false; + description = '' + Enable Web UI for administration. Bound to the specified + <literal>httpListenAddress</literal> and + <literal>httpListenPort</literal>. + ''; + }; + + storagePath = mkOption { + type = types.path; + default = "/var/lib/resilio-sync/"; + description = '' + Where BitTorrent Sync will store it's database files (containing + things like username info and licenses). Generally, you should not + need to ever change this. + ''; + }; + + apiKey = mkOption { + type = types.str; + default = ""; + description = "API key, which enables the developer API."; + }; + + directoryRoot = mkOption { + type = types.str; + default = ""; + example = "/media"; + description = "Default directory to add folders in the web UI."; + }; + + sharedFolders = mkOption { + default = []; + example = + [ { secret = "AHMYFPCQAHBM7LQPFXQ7WV6Y42IGUXJ5Y"; + directory = "/home/user/sync_test"; + useRelayServer = true; + useTracker = true; + useDHT = false; + searchLAN = true; + useSyncTrash = true; + knownHosts = [ + "192.168.1.2:4444" + "192.168.1.3:4444" + ]; + } + ]; + description = '' + Shared folder list. If enabled, web UI must be + disabled. Secrets can be generated using <literal>rslsync + --generate-secret</literal>. Note that this secret will be + put inside the Nix store, so it is realistically not very + secret. + + If you would like to be able to modify the contents of this + directories, it is recommended that you make your user a + member of the <literal>resilio</literal> group. + + Directories in this list should be in the + <literal>resilio</literal> group, and that group must have + write access to the directory. It is also recommended that + <literal>chmod g+s</literal> is applied to the directory + so that any sub directories created will also belong to + the <literal>resilio</literal> group. Also, + <literal>setfacl -d -m group:resilio:rwx</literal> and + <literal>setfacl -m group:resilio:rwx</literal> should also + be applied so that the sub directories are writable by + the group. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = + [ { assertion = cfg.deviceName != ""; + message = "Device name cannot be empty."; + } + { assertion = cfg.enableWebUI -> cfg.sharedFolders == []; + message = "If using shared folders, the web UI cannot be enabled."; + } + { assertion = cfg.apiKey != "" -> cfg.enableWebUI; + message = "If you're using an API key, you must enable the web server."; + } + ]; + + users.extraUsers.rslsync = { + description = "Resilio Sync Service user"; + home = cfg.storagePath; + createHome = true; + uid = config.ids.uids.rslsync; + group = "rslsync"; + }; + + users.extraGroups = [ { name = "rslsync"; } ]; + + systemd.services.resilio = with pkgs; { + description = "Resilio Sync Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "local-fs.target" ]; + serviceConfig = { + Restart = "on-abort"; + UMask = "0002"; + User = "rslsync"; + ExecStart = '' + ${resilioSync}/bin/rslsync --nodaemon --config ${configFile} + ''; + }; + }; + }; +} diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix index 37f84f0903c3..ad3b65150b01 100644 --- a/nixos/modules/services/x11/window-managers/qtile.nix +++ b/nixos/modules/services/x11/window-managers/qtile.nix @@ -15,7 +15,7 @@ in services.xserver.windowManager.session = [{ name = "qtile"; start = '' - ${pkgs.qtile}/bin/qtile + ${pkgs.qtile}/bin/qtile & waitPID=$! ''; }]; |