diff options
Diffstat (limited to 'nixos')
22 files changed, 456 insertions, 91 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index e54bec81b2f3f..0fd0382998c20 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -121,6 +121,15 @@ </listitem> <listitem> <para> + <literal>services.mastodon</literal> gained a tootctl wrapped + named <literal>mastodon-tootctl</literal> similar to + <literal>nextcloud-occ</literal> which can be executed from + any user and switches to the configured mastodon user with + sudo and sources the environment variables. + </para> + </listitem> + <listitem> + <para> A new <literal>virtualisation.rosetta</literal> module was added to allow running <literal>x86_64</literal> binaries through @@ -139,6 +148,13 @@ the Nix store. </para> </listitem> + <listitem> + <para> + The <literal>unifi-poller</literal> package and corresponding + NixOS module have been renamed to <literal>unpoller</literal> + to match upstream. + </para> + </listitem> </itemizedlist> </section> </section> diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index 0e5b97c898460..39550d44733ad 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -41,6 +41,10 @@ In addition to numerous new and upgraded packages, this release has the followin - The module for the application firewall `opensnitch` got the ability to configure rules. Available as [services.opensnitch.rules](#opt-services.opensnitch.rules) +- `services.mastodon` gained a tootctl wrapped named `mastodon-tootctl` similar to `nextcloud-occ` which can be executed from any user and switches to the configured mastodon user with sudo and sources the environment variables. + - A new `virtualisation.rosetta` module was added to allow running `x86_64` binaries through [Rosetta](https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment) inside virtualised NixOS guests on Apple silicon. This feature works by default with the [UTM](https://docs.getutm.app/) virtualisation [package](https://search.nixos.org/packages?channel=unstable&show=utm&from=0&size=1&sort=relevance&type=packages&query=utm). - Resilio sync secret keys can now be provided using a secrets file at runtime, preventing these secrets from ending up in the Nix store. + +- The `unifi-poller` package and corresponding NixOS module have been renamed to `unpoller` to match upstream. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 59d6cf165f180..9faa58409b19d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -211,10 +211,12 @@ ./programs/plotinus.nix ./programs/proxychains.nix ./programs/qt5ct.nix + ./programs/rog-control-center.nix ./programs/rust-motd.nix ./programs/screen.nix ./programs/sedutil.nix ./programs/seahorse.nix + ./programs/skim.nix ./programs/slock.nix ./programs/shadow.nix ./programs/spacefm.nix @@ -450,6 +452,7 @@ ./services/hardware/acpid.nix ./services/hardware/actkbd.nix ./services/hardware/argonone.nix + ./services/hardware/asusd.nix ./services/hardware/auto-cpufreq.nix ./services/hardware/bluetooth.nix ./services/hardware/bolt.nix @@ -477,6 +480,7 @@ ./services/hardware/sane_extra_backends/brscan5.nix ./services/hardware/sane_extra_backends/dsseries.nix ./services/hardware/spacenavd.nix + ./services/hardware/supergfxd.nix ./services/hardware/tcsd.nix ./services/hardware/tlp.nix ./services/hardware/thinkfan.nix @@ -724,7 +728,7 @@ ./services/monitoring/thanos.nix ./services/monitoring/tremor-rs.nix ./services/monitoring/tuptime.nix - ./services/monitoring/unifi-poller.nix + ./services/monitoring/unpoller.nix ./services/monitoring/ups.nix ./services/monitoring/uptime.nix ./services/monitoring/vmagent.nix diff --git a/nixos/modules/programs/firefox.nix b/nixos/modules/programs/firefox.nix index 76e6c1a553f3a..dfd912cdf5c11 100644 --- a/nixos/modules/programs/firefox.nix +++ b/nixos/modules/programs/firefox.nix @@ -5,6 +5,8 @@ with lib; let cfg = config.programs.firefox; + nmh = cfg.nativeMessagingHosts; + policyFormat = pkgs.formats.json { }; organisationInfo = '' @@ -15,15 +17,15 @@ let given control of your browser, unless of course they also control your NixOS configuration. ''; - -in { +in +{ options.programs.firefox = { enable = mkEnableOption (mdDoc "the Firefox web browser"); package = mkOption { - description = mdDoc "Firefox package to use."; type = types.package; default = pkgs.firefox; + description = mdDoc "Firefox package to use."; defaultText = literalExpression "pkgs.firefox"; relatedPackages = [ "firefox" @@ -31,12 +33,12 @@ in { "firefox-bin" "firefox-devedition-bin" "firefox-esr" - "firefox-esr-wayland" - "firefox-wayland" ]; }; policies = mkOption { + type = policyFormat.type; + default = { }; description = mdDoc '' Group policies to install. @@ -48,43 +50,97 @@ in { ${organisationInfo} ''; - type = policyFormat.type; - default = {}; }; preferences = mkOption { + type = with types; attrsOf (oneOf [ bool int string ]); + default = { }; description = mdDoc '' - Preferences to set from `about://config`. + Preferences to set from `about:config`. Some of these might be able to be configured more ergonomically using policies. ${organisationInfo} ''; - type = with types; attrsOf (oneOf [ bool int string ]); - default = {}; + }; + + preferencesStatus = mkOption { + type = types.enum [ "default" "locked" "user" "clear" ]; + default = "locked"; + description = mdDoc '' + The status of `firefox.preferences`. + + `status` can assume the following values: + - `"default"`: Preferences appear as default. + - `"locked"`: Preferences appear as default and can't be changed. + - `"user"`: Preferences appear as changed. + - `"clear"`: Value has no effect. Resets to factory defaults on each startup. + ''; + }; + + autoConfig = mkOption { + type = types.lines; + default = ""; + description = mdDoc '' + AutoConfig files can be used to set and lock preferences that are not covered + by the policies.json for Mac and Linux. This method can be used to automatically + change user preferences or prevent the end user from modifiying specific + preferences by locking them. More info can be found in https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig. + ''; + }; + + nativeMessagingHosts = mapAttrs (_: v: mkEnableOption (mdDoc v)) { + browserpass = "Browserpass support"; + bukubrow = "Bukubrow support"; + ff2mpv = "ff2mpv support"; + fxCast = "fx_cast support"; + gsconnect = "GSConnect support"; + jabref = "JabRef support"; + passff = "PassFF support"; + tridactyl = "Tridactyl support"; + ugetIntegrator = "Uget Integrator support"; }; }; config = mkIf cfg.enable { - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ + (cfg.package.override { + extraPrefs = cfg.autoConfig; + extraNativeMessagingHosts = with pkgs; optionals nmh.ff2mpv [ + ff2mpv + ] ++ optionals nmh.gsconnect [ + gnomeExtensions.gsconnect + ] ++ optionals nmh.jabref [ + jabref + ] ++ optionals nmh.passff [ + passff-host + ]; + }) + ]; + + nixpkgs.config.firefox = { + enableBrowserpass = nmh.browserpass; + enableBukubrow = nmh.bukubrow; + enableTridactylNative = nmh.tridactyl; + enableUgetIntegrator = nmh.ugetIntegrator; + enableFXCastBridge = nmh.fxCast; + }; - environment.etc."firefox/policies/policies.json".source = - let policiesJSON = - policyFormat.generate - "firefox-policies.json" - { inherit (cfg) policies; }; - in mkIf (cfg.policies != {}) "${policiesJSON}"; + environment.etc = + let + policiesJSON = policyFormat.generate "firefox-policies.json" { inherit (cfg) policies; }; + in + mkIf (cfg.policies != { }) { + "firefox/policies/policies.json".source = "${policiesJSON}"; + }; # Preferences are converted into a policy - programs.firefox.policies = - mkIf (cfg.preferences != {}) - { - Preferences = (mapAttrs (name: value: { - Value = value; - Status = "locked"; - }) cfg.preferences); - }; + programs.firefox.policies = mkIf (cfg.preferences != { }) { + Preferences = (mapAttrs + (_: value: { Value = value; Status = cfg.preferencesStatus; }) + cfg.preferences); + }; }; meta.maintainers = with maintainers; [ danth ]; diff --git a/nixos/modules/programs/fzf.nix b/nixos/modules/programs/fzf.nix index 0452bf4262276..eda4eacde4ac9 100644 --- a/nixos/modules/programs/fzf.nix +++ b/nixos/modules/programs/fzf.nix @@ -5,18 +5,8 @@ let in { options = { programs.fzf = { - fuzzyCompletion = mkOption { - type = types.bool; - description = lib.mdDoc "Whether to use fzf for fuzzy completion"; - default = false; - example = true; - }; - keybindings = mkOption { - type = types.bool; - description = lib.mdDoc "Whether to set up fzf keybindings"; - default = false; - example = true; - }; + fuzzyCompletion = mkEnableOption (mdDoc "fuzzy completion with fzf"); + keybindings = mkEnableOption (mdDoc "fzf keybindings"); }; }; config = { diff --git a/nixos/modules/programs/rog-control-center.nix b/nixos/modules/programs/rog-control-center.nix new file mode 100644 index 0000000000000..4aef5143ac7ff --- /dev/null +++ b/nixos/modules/programs/rog-control-center.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.rog-control-center; +in +{ + options = { + programs.rog-control-center = { + enable = lib.mkEnableOption (lib.mdDoc "the rog-control-center application"); + + autoStart = lib.mkOption { + default = false; + type = lib.types.bool; + description = lib.mdDoc "Whether rog-control-center should be started automatically."; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + pkgs.asusctl + (lib.mkIf cfg.autoStart (pkgs.makeAutostartItem { name = "rog-control-center"; package = pkgs.asusctl; })) + ]; + + services.asusd.enable = true; + }; + + meta.maintainers = pkgs.asusctl.meta.maintainers; +} diff --git a/nixos/modules/programs/skim.nix b/nixos/modules/programs/skim.nix new file mode 100644 index 0000000000000..1333cdd30ab23 --- /dev/null +++ b/nixos/modules/programs/skim.nix @@ -0,0 +1,30 @@ +{ pkgs, config, lib, ... }: +let + inherit (lib) mdDoc mkEnableOption mkPackageOption optional optionalString; + cfg = config.programs.skim; +in +{ + options = { + programs.skim = { + fuzzyCompletion = mkEnableOption (mdDoc "fuzzy Completion with skim"); + keybindings = mkEnableOption (mdDoc "skim keybindings"); + package = mkPackageOption pkgs "skim" {}; + }; + }; + + config = { + environment.systemPackages = optional (cfg.keybindings || cfg.fuzzyCompletion) cfg.package; + + programs.bash.interactiveShellInit = optionalString cfg.fuzzyCompletion '' + source ${cfg.package}/share/skim/completion.bash + '' + optionalString cfg.keybindings '' + source ${cfg.package}/share/skim/key-bindings.bash + ''; + + programs.zsh.interactiveShellInit = optionalString cfg.fuzzyCompletion '' + source ${cfg.package}/share/skim/completion.zsh + '' + optionalString cfg.keybindings '' + source ${cfg.package}/share/skim/key-bindings.zsh + ''; + }; +} diff --git a/nixos/modules/services/hardware/asusd.nix b/nixos/modules/services/hardware/asusd.nix new file mode 100644 index 0000000000000..f0751c4402516 --- /dev/null +++ b/nixos/modules/services/hardware/asusd.nix @@ -0,0 +1,114 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.asusd; + json = pkgs.formats.json { }; + toml = pkgs.formats.toml { }; +in +{ + options = { + services.asusd = { + enable = lib.mkEnableOption (lib.mdDoc "the asusd service for ASUS ROG laptops"); + + enableUserService = lib.mkOption { + type = lib.types.bool; + default = false; + description = lib.mdDoc '' + Activate the asusd-user service. + ''; + }; + + animeConfig = lib.mkOption { + type = json.type; + default = { }; + description = lib.mdDoc '' + The content of /etc/asusd/anime.conf. + See https://asus-linux.org/asusctl/#anime-control. + ''; + }; + + asusdConfig = lib.mkOption { + type = json.type; + default = { }; + description = lib.mdDoc '' + The content of /etc/asusd/asusd.conf. + See https://asus-linux.org/asusctl/. + ''; + }; + + auraConfig = lib.mkOption { + type = json.type; + default = { }; + description = lib.mdDoc '' + The content of /etc/asusd/aura.conf. + See https://asus-linux.org/asusctl/#led-keyboard-control. + ''; + }; + + profileConfig = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = ""; + description = lib.mdDoc '' + The content of /etc/asusd/profile.conf. + See https://asus-linux.org/asusctl/#profiles. + ''; + }; + + ledModesConfig = lib.mkOption { + type = lib.types.nullOr toml.type; + default = null; + description = lib.mdDoc '' + The content of /etc/asusd/asusd-ledmodes.toml. Leave `null` to use default settings. + See https://asus-linux.org/asusctl/#led-keyboard-control. + ''; + }; + + userLedModesConfig = lib.mkOption { + type = lib.types.nullOr toml.type; + default = null; + description = lib.mdDoc '' + The content of /etc/asusd/asusd-user-ledmodes.toml. + See https://asus-linux.org/asusctl/#led-keyboard-control. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ pkgs.asusctl ]; + + environment.etc = + let + maybeConfig = name: cfg: lib.mkIf (cfg != { }) { + source = json.generate name cfg; + mode = "0644"; + }; + in + { + "asusd/anime.conf" = maybeConfig "anime.conf" cfg.animeConfig; + "asusd/asusd.conf" = maybeConfig "asusd.conf" cfg.asusdConfig; + "asusd/aura.conf" = maybeConfig "aura.conf" cfg.auraConfig; + "asusd/profile.conf" = lib.mkIf (cfg.profileConfig != null) { + source = pkgs.writeText "profile.conf" cfg.profileConfig; + mode = "0644"; + }; + "asusd/asusd-ledmodes.toml" = { + source = + if cfg.ledModesConfig == null + then "${pkgs.asusctl}/share/asusd/data/asusd-ledmodes.toml" + else toml.generate "asusd-ledmodes.toml" cfg.ledModesConfig; + mode = "0644"; + }; + }; + + services.dbus.enable = true; + systemd.packages = [ pkgs.asusctl ]; + services.dbus.packages = [ pkgs.asusctl ]; + services.udev.packages = [ pkgs.asusctl ]; + services.supergfxd.enable = true; + + systemd.user.services.asusd-user.enable = cfg.enableUserService; + }; + + meta.maintainers = pkgs.asusctl.meta.maintainers; +} diff --git a/nixos/modules/services/hardware/supergfxd.nix b/nixos/modules/services/hardware/supergfxd.nix new file mode 100644 index 0000000000000..abb6bedb98ff3 --- /dev/null +++ b/nixos/modules/services/hardware/supergfxd.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.supergfxd; + ini = pkgs.formats.ini { }; +in +{ + options = { + services.supergfxd = { + enable = lib.mkEnableOption (lib.mdDoc "Enable the supergfxd service"); + + settings = lib.mkOption { + type = lib.types.nullOr ini.type; + default = null; + description = lib.mdDoc '' + The content of /etc/supergfxd.conf. + See https://gitlab.com/asus-linux/supergfxctl/#config-options-etcsupergfxdconf. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ pkgs.supergfxctl ]; + + environment.etc."supergfxd.conf" = lib.mkIf (cfg.settings != null) (ini.generate "supergfxd.conf" cfg.settings); + + services.dbus.enable = true; + + systemd.packages = [ pkgs.supergfxctl ]; + systemd.services.supergfxd.wantedBy = [ "multi-user.target" ]; + + services.dbus.packages = [ pkgs.supergfxctl ]; + services.udev.packages = [ pkgs.supergfxctl ]; + }; + + meta.maintainers = pkgs.supergfxctl.meta.maintainers; +} diff --git a/nixos/modules/services/home-automation/zigbee2mqtt.nix b/nixos/modules/services/home-automation/zigbee2mqtt.nix index 71f6e7a258404..796de3a491e49 100644 --- a/nixos/modules/services/home-automation/zigbee2mqtt.nix +++ b/nixos/modules/services/home-automation/zigbee2mqtt.nix @@ -119,9 +119,8 @@ in ]; SystemCallArchitectures = "native"; SystemCallFilter = [ - "@system-service" - "~@privileged" - "~@resources" + "@system-service @pkey" + "~@privileged @resources" ]; UMask = "0077"; }; diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix index 22b78981b2cce..2451f46ba7d75 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters.nix @@ -73,7 +73,7 @@ let "tor" "unbound" "unifi" - "unifi-poller" + "unpoller" "v2ray" "varnish" "wireguard" @@ -230,6 +230,10 @@ in options.services.prometheus.exporters = mkOption { type = types.submodule { options = (mkSubModules); + imports = [ + ../../../misc/assertions.nix + (lib.mkRenamedOptionModule [ "unifi-poller" ] [ "unpoller" ]) + ]; }; description = lib.mdDoc "Prometheus exporter configuration"; default = {}; @@ -293,13 +297,14 @@ in Please specify either 'services.prometheus.exporters.sql.configuration' or 'services.prometheus.exporters.sql.configFile' ''; - } ] ++ (flip map (attrNames cfg) (exporter: { + } ] ++ (flip map (attrNames exporterOpts) (exporter: { assertion = cfg.${exporter}.firewallFilter != null -> cfg.${exporter}.openFirewall; message = '' The `firewallFilter'-option of exporter ${exporter} doesn't have any effect unless `openFirewall' is set to `true'! ''; - })); + })) ++ config.services.prometheus.exporters.assertions; + warnings = config.services.prometheus.exporters.warnings; }] ++ [(mkIf config.services.minio.enable { services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000"; services.prometheus.exporters.minio.minioAccessKey = mkDefault config.services.minio.accessKey; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix index 35de31df88e6d..5cd1e2c65e906 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unifi-poller.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix @@ -3,9 +3,9 @@ with lib; let - cfg = config.services.prometheus.exporters.unifi-poller; + cfg = config.services.prometheus.exporters.unpoller; - configFile = pkgs.writeText "prometheus-unifi-poller-exporter.json" (generators.toJSON {} { + configFile = pkgs.writeText "prometheus-unpoller-exporter.json" (generators.toJSON {} { poller = { inherit (cfg.log) debug quiet; }; unifi = { inherit (cfg) controllers; }; influxdb.disable = true; @@ -21,8 +21,8 @@ in { port = 9130; extraOpts = { - inherit (options.services.unifi-poller.unifi) controllers; - inherit (options.services.unifi-poller) loki; + inherit (options.services.unpoller.unifi) controllers; + inherit (options.services.unpoller) loki; log = { debug = mkEnableOption (lib.mdDoc "debug logging including line numbers, high resolution timestamps, per-device logs."); quiet = mkEnableOption (lib.mdDoc "startup and error logs only."); @@ -31,7 +31,7 @@ in { }; serviceOpts.serviceConfig = { - ExecStart = "${pkgs.unifi-poller}/bin/unpoller --config ${configFile}"; + ExecStart = "${pkgs.unpoller}/bin/unpoller --config ${configFile}"; DynamicUser = false; }; } diff --git a/nixos/modules/services/monitoring/unifi-poller.nix b/nixos/modules/services/monitoring/unpoller.nix index b30e28a3ecc93..f0ced5513d64b 100644 --- a/nixos/modules/services/monitoring/unifi-poller.nix +++ b/nixos/modules/services/monitoring/unpoller.nix @@ -3,15 +3,19 @@ with lib; let - cfg = config.services.unifi-poller; + cfg = config.services.unpoller; - configFile = pkgs.writeText "unifi-poller.json" (generators.toJSON {} { + configFile = pkgs.writeText "unpoller.json" (generators.toJSON {} { inherit (cfg) poller influxdb loki prometheus unifi; }); in { - options.services.unifi-poller = { - enable = mkEnableOption (lib.mdDoc "unifi-poller"); + imports = [ + (lib.mkRenamedOptionModule [ "services" "unifi-poller" ] [ "services" "unpoller" ]) + ]; + + options.services.unpoller = { + enable = mkEnableOption (lib.mdDoc "unpoller"); poller = { debug = mkOption { @@ -86,8 +90,8 @@ in { }; pass = mkOption { type = types.path; - default = pkgs.writeText "unifi-poller-influxdb-default.password" "unifipoller"; - defaultText = literalExpression "unifi-poller-influxdb-default.password"; + default = pkgs.writeText "unpoller-influxdb-default.password" "unifipoller"; + defaultText = literalExpression "unpoller-influxdb-default.password"; description = lib.mdDoc '' Path of a file containing the password for influxdb. This file needs to be readable by the unifi-poller user. @@ -135,8 +139,8 @@ in { }; pass = mkOption { type = types.path; - default = pkgs.writeText "unifi-poller-loki-default.password" ""; - defaultText = "unifi-poller-influxdb-default.password"; + default = pkgs.writeText "unpoller-loki-default.password" ""; + defaultText = "unpoller-influxdb-default.password"; description = lib.mdDoc '' Path of a file containing the password for Loki. This file needs to be readable by the unifi-poller user. @@ -184,8 +188,8 @@ in { }; pass = mkOption { type = types.path; - default = pkgs.writeText "unifi-poller-unifi-default.password" "unifi"; - defaultText = literalExpression "unifi-poller-unifi-default.password"; + default = pkgs.writeText "unpoller-unifi-default.password" "unifi"; + defaultText = literalExpression "unpoller-unifi-default.password"; description = lib.mdDoc '' Path of a file containing the password for the unifi service user. This file needs to be readable by the unifi-poller user. @@ -303,7 +307,7 @@ in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = "${pkgs.unifi-poller}/bin/unifi-poller --config ${configFile}"; + ExecStart = "${pkgs.unpoller}/bin/unpoller --config ${configFile}"; Restart = "always"; PrivateTmp = true; ProtectHome = true; diff --git a/nixos/modules/services/web-apps/mastodon.nix b/nixos/modules/services/web-apps/mastodon.nix index a221186adf64c..8122c24494912 100644 --- a/nixos/modules/services/web-apps/mastodon.nix +++ b/nixos/modules/services/web-apps/mastodon.nix @@ -92,12 +92,18 @@ let ] else [] ) env)))); - mastodonEnv = pkgs.writeShellScriptBin "mastodon-env" '' + mastodonTootctl = pkgs.writeShellScriptBin "mastodon-tootctl" '' + #! ${pkgs.runtimeShell} set -a export RAILS_ROOT="${cfg.package}" source "${envFile}" source /var/lib/mastodon/.secrets_env - eval -- "\$@" + + sudo=exec + if [[ "$USER" != ${cfg.user} ]]; then + sudo='exec /run/wrappers/bin/sudo -u ${cfg.user} --preserve-env' + fi + $sudo ${cfg.package}/bin/tootctl "$@" ''; in { @@ -133,15 +139,10 @@ in { description = lib.mdDoc '' User under which mastodon runs. If it is set to "mastodon", that user will be created, otherwise it should be set to the - name of a user created elsewhere. In both cases, - `mastodon` and a package containing only - the shell script `mastodon-env` will be added to - the user's package set. To run a command from - `mastodon` such as `tootctl` - with the environment configured by this module use - `mastodon-env`, as in: - - `mastodon-env tootctl accounts create newuser --email newuser@example.com` + name of a user created elsewhere. + In both cases, the `mastodon` package will be added to the user's package set + and a tootctl wrapper to system packages that switches to the configured account + and load the right environment. ''; type = lib.types.str; default = "mastodon"; @@ -485,6 +486,8 @@ in { } ]; + environment.systemPackages = [ mastodonTootctl ]; + systemd.services.mastodon-init-dirs = { script = '' umask 077 @@ -704,7 +707,7 @@ in { inherit (cfg) group; }; }) - (lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package mastodonEnv pkgs.imagemagick ]) + (lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package pkgs.imagemagick ]) ]; users.groups.${cfg.group}.members = lib.optional cfg.configureNginx config.services.nginx.user; diff --git a/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixos/modules/services/x11/desktop-managers/cinnamon.nix index 25de29554b1eb..8e6a44428fce1 100644 --- a/nixos/modules/services/x11/desktop-managers/cinnamon.nix +++ b/nixos/modules/services/x11/desktop-managers/cinnamon.nix @@ -74,6 +74,10 @@ in name = mkDefault "Mint-X-Dark"; package = mkDefault pkgs.cinnamon.mint-x-icons; }; + cursorTheme = mkIf (notExcluded pkgs.cinnamon.mint-cursor-themes) { + name = mkDefault "Bibata-Modern-Classic"; + package = mkDefault pkgs.cinnamon.mint-cursor-themes; + }; }; services.xserver.displayManager.sessionCommands = '' if test "$XDG_CURRENT_DESKTOP" = "Cinnamon"; then diff --git a/nixos/modules/services/x11/display-managers/lightdm-greeters/slick.nix b/nixos/modules/services/x11/display-managers/lightdm-greeters/slick.nix index 00fa8af71dc54..4456374cc569e 100644 --- a/nixos/modules/services/x11/display-managers/lightdm-greeters/slick.nix +++ b/nixos/modules/services/x11/display-managers/lightdm-greeters/slick.nix @@ -11,6 +11,7 @@ let theme = cfg.theme.package; icons = cfg.iconTheme.package; font = cfg.font.package; + cursors = cfg.cursorTheme.package; slickGreeterConf = writeText "slick-greeter.conf" '' [Greeter] @@ -18,6 +19,8 @@ let theme-name=${cfg.theme.name} icon-theme-name=${cfg.iconTheme.name} font-name=${cfg.font.name} + cursor-theme-name=${cfg.cursorTheme.name} + cursor-theme-size=${toString cfg.cursorTheme.size} draw-user-backgrounds=${boolToString cfg.draw-user-backgrounds} ${cfg.extraConfig} ''; @@ -84,6 +87,33 @@ in }; }; + cursorTheme = { + package = mkOption { + type = types.package; + default = pkgs.gnome.adwaita-icon-theme; + defaultText = literalExpression "pkgs.gnome.adwaita-icon-theme"; + description = lib.mdDoc '' + The package path that contains the cursor theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "Adwaita"; + description = lib.mdDoc '' + Name of the cursor theme to use for the lightdm-slick-greeter. + ''; + }; + + size = mkOption { + type = types.int; + default = 24; + description = lib.mdDoc '' + Size of the cursor theme to use for the lightdm-slick-greeter. + ''; + }; + }; + draw-user-backgrounds = mkEnableOption (lib.mdDoc "draw user backgrounds"); extraConfig = mkOption { @@ -107,6 +137,7 @@ in }; environment.systemPackages = [ + cursors icons theme ]; diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix index 673655f20ee84..701d242abc154 100644 --- a/nixos/modules/system/boot/initrd-ssh.nix +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -73,6 +73,15 @@ in ''; }; + ignoreEmptyHostKeys = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Allow leaving {option}`config.boot.initrd.network.ssh` empty, + to deploy ssh host keys out of band. + ''; + }; + authorizedKeys = mkOption { type = types.listOf types.str; default = config.users.users.root.openssh.authorizedKeys.keys; @@ -141,7 +150,7 @@ in } { - assertion = cfg.hostKeys != []; + assertion = (cfg.hostKeys != []) || cfg.ignoreEmptyHostKeys; message = '' You must now pre-generate the host keys for initrd SSH. See the boot.initrd.network.ssh.hostKeys documentation diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index 28abf820ec097..5f40ee9c08dc7 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -928,6 +928,8 @@ let type = types.bool; description = lib.mdDoc '' Whether to manage network configuration using {command}`systemd-network`. + + This also enables {option}`systemd.networkd.enable`. ''; }; diff --git a/nixos/modules/virtualisation/lxd.nix b/nixos/modules/virtualisation/lxd.nix index e3eb519b7dddf..c06716e5eb605 100644 --- a/nixos/modules/virtualisation/lxd.nix +++ b/nixos/modules/virtualisation/lxd.nix @@ -140,7 +140,8 @@ in { ]; documentation = [ "man:lxd(1)" ]; - path = optional cfg.zfsSupport config.boot.zfs.package; + path = [ pkgs.util-linux ] + ++ optional cfg.zfsSupport config.boot.zfs.package; serviceConfig = { ExecStart = "@${cfg.package}/bin/lxd lxd --group lxd"; diff --git a/nixos/tests/grocy.nix b/nixos/tests/grocy.nix index fe0ddd341486b..48bbc9f7d3fa2 100644 --- a/nixos/tests/grocy.nix +++ b/nixos/tests/grocy.nix @@ -14,6 +14,9 @@ import ./make-test-python.nix ({ pkgs, ... }: { }; testScript = '' + from base64 import b64encode + from urllib.parse import quote + machine.start() machine.wait_for_open_port(80) machine.wait_for_unit("multi-user.target") @@ -42,6 +45,29 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine.succeed("curl -sSI http://localhost/api/tasks 2>&1 | grep '401 Unauthorized'") + file_name = "test.txt" + file_name_base64 = b64encode(file_name.encode('ascii')).decode('ascii') + file_name_base64_urlencode = quote(file_name_base64) + + machine.succeed( + f"echo Sample equipment manual > /tmp/{file_name}" + ) + + machine.succeed( + f"curl -sSf -X 'PUT' -b 'grocy_session={cookie}' " + + f" 'http://localhost/api/files/equipmentmanuals/{file_name_base64_urlencode}' " + + " --header 'Accept: */*' " + + " --header 'Content-Type: application/octet-stream' " + + f" --data-binary '@/tmp/{file_name}' " + ) + + machine.succeed( + f"curl -sSf -X 'GET' -b 'grocy_session={cookie}' " + + f" 'http://localhost/api/files/equipmentmanuals/{file_name_base64_urlencode}' " + + " --header 'Accept: application/octet-stream' " + + f" | cmp /tmp/{file_name}" + ) + machine.shutdown() ''; }) diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index d91fc52f1cb45..cdf666378fa37 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -1244,15 +1244,15 @@ let ''; }; - unifi-poller = { - nodeName = "unifi_poller"; + unpoller = { + nodeName = "unpoller"; exporterConfig.enable = true; exporterConfig.controllers = [{ }]; exporterTest = '' - wait_for_unit("prometheus-unifi-poller-exporter.service") + wait_for_unit("prometheus-unpoller-exporter.service") wait_for_open_port(9130) succeed( - "curl -sSf localhost:9130/metrics | grep 'unifipoller_build_info{.\\+} 1'" + "curl -sSf localhost:9130/metrics | grep 'unpoller_build_info{.\\+} 1'" ) ''; }; diff --git a/nixos/tests/web-apps/mastodon.nix b/nixos/tests/web-apps/mastodon.nix index d3d53dc319469..f10cb8cdc6771 100644 --- a/nixos/tests/web-apps/mastodon.nix +++ b/nixos/tests/web-apps/mastodon.nix @@ -104,24 +104,24 @@ in # Simple check tootctl commands # Check Mastodon version - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl version' | grep '${pkgs.mastodon.version}'") + server.succeed("mastodon-tootctl version | grep '${pkgs.mastodon.version}'") # Manage accounts - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks add example.com'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'example.com'") - server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks list' | grep 'mastodon.local'") - server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create alice --email=alice@example.com'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl email_domain_blocks remove example.com'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts create bob --email=bob@example.com'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts approve bob'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl accounts delete bob'") + server.succeed("mastodon-tootctl email_domain_blocks add example.com") + server.succeed("mastodon-tootctl email_domain_blocks list | grep example.com") + server.fail("mastodon-tootctl email_domain_blocks list | grep mastodon.local") + server.fail("mastodon-tootctl accounts create alice --email=alice@example.com") + server.succeed("mastodon-tootctl email_domain_blocks remove example.com") + server.succeed("mastodon-tootctl accounts create bob --email=bob@example.com") + server.succeed("mastodon-tootctl accounts approve bob") + server.succeed("mastodon-tootctl accounts delete bob") # Manage IP access - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks add 192.168.0.0/16 --severity=no_access'") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks export' | grep '192.168.0.0/16'") - server.fail("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks export' | grep '172.16.0.0/16'") + server.succeed("mastodon-tootctl ip_blocks add 192.168.0.0/16 --severity=no_access") + server.succeed("mastodon-tootctl ip_blocks export | grep 192.168.0.0/16") + server.fail("mastodon-tootctl ip_blocks export | grep 172.16.0.0/16") client.fail("curl --fail https://mastodon.local/about") - server.succeed("su - mastodon -s /bin/sh -c 'mastodon-env tootctl ip_blocks remove 192.168.0.0/16'") + server.succeed("mastodon-tootctl ip_blocks remove 192.168.0.0/16") client.succeed("curl --fail https://mastodon.local/about") server.shutdown() |