diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/configuration/x-windows.chapter.md | 10 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2405.section.md | 6 | ||||
-rw-r--r-- | nixos/modules/services/desktops/flatpak.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/slskd.nix | 326 | ||||
-rw-r--r-- | nixos/modules/services/x11/xserver.nix | 2 | ||||
-rw-r--r-- | nixos/modules/virtualisation/incus.nix | 164 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/firefoxpwa.nix | 36 | ||||
-rw-r--r-- | nixos/tests/incus/container.nix | 15 | ||||
-rw-r--r-- | nixos/tests/incus/default.nix | 18 | ||||
-rw-r--r-- | nixos/tests/incus/lxd-to-incus.nix | 2 | ||||
-rw-r--r-- | nixos/tests/tracee.nix | 93 |
12 files changed, 460 insertions, 215 deletions
diff --git a/nixos/doc/manual/configuration/x-windows.chapter.md b/nixos/doc/manual/configuration/x-windows.chapter.md index bf1872ae01ace..0e8e38b83dcdc 100644 --- a/nixos/doc/manual/configuration/x-windows.chapter.md +++ b/nixos/doc/manual/configuration/x-windows.chapter.md @@ -146,14 +146,12 @@ default because it's not free software. You can enable it as follows: services.xserver.videoDrivers = [ "nvidia" ]; ``` -Or if you have an older card, you may have to use one of the legacy -drivers: +If you have an older card, you may have to use one of the legacy drivers: ```nix -services.xserver.videoDrivers = [ "nvidiaLegacy470" ]; -services.xserver.videoDrivers = [ "nvidiaLegacy390" ]; -services.xserver.videoDrivers = [ "nvidiaLegacy340" ]; -services.xserver.videoDrivers = [ "nvidiaLegacy304" ]; +hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470; +hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390; +hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340; ``` You may need to reboot after enabling this driver to prevent a clash diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 8bf84c2d32c57..92018e384847e 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -455,6 +455,12 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - The module `services.github-runner` has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration. +- The `services.slskd` has been refactored to include more configuation options in + the freeform `services.slskd.settings` option, and some defaults (including listen ports) + have been changed to match the upstream defaults. Additionally, disk logging is now + disabled by default, and the log rotation timer has been removed. + The nginx virtualhost option is now of the `vhost-options` type. + - The `btrbk` module now automatically selects and provides required compression program depending on the configured `stream_compress` option. Since this replaces the need for the `extraPackages` option, this option will be diff --git a/nixos/modules/services/desktops/flatpak.nix b/nixos/modules/services/desktops/flatpak.nix index 4c26e6874023a..62ef38a3d5548 100644 --- a/nixos/modules/services/desktops/flatpak.nix +++ b/nixos/modules/services/desktops/flatpak.nix @@ -32,6 +32,8 @@ in { security.polkit.enable = true; + fonts.fontDir.enable = true; + services.dbus.packages = [ pkgs.flatpak ]; systemd.packages = [ pkgs.flatpak ]; diff --git a/nixos/modules/services/web-apps/slskd.nix b/nixos/modules/services/web-apps/slskd.nix index 580f66ec3ac90..15a5fd1177adf 100644 --- a/nixos/modules/services/web-apps/slskd.nix +++ b/nixos/modules/services/web-apps/slskd.nix @@ -2,120 +2,248 @@ let settingsFormat = pkgs.formats.yaml {}; + defaultUser = "slskd"; in { options.services.slskd = with lib; with types; { enable = mkEnableOption "enable slskd"; - rotateLogs = mkEnableOption "enable an unit and timer that will rotate logs in /var/slskd/logs"; + package = mkPackageOptionMD pkgs "slskd" { }; - package = mkPackageOption pkgs "slskd" { }; + user = mkOption { + type = types.str; + default = defaultUser; + description = "User account under which slskd runs."; + }; - nginx = mkOption { - description = lib.mdDoc "options for nginx"; - example = { - enable = true; - domain = "example.com"; - contextPath = "/slskd"; - }; - type = submodule ({name, config, ...}: { - options = { - enable = mkEnableOption "enable nginx as a reverse proxy"; + group = mkOption { + type = types.str; + default = defaultUser; + description = "Group under which slskd runs."; + }; - domainName = mkOption { - type = str; - description = "Domain you want to use"; - }; - contextPath = mkOption { - type = types.path; - default = "/"; - description = lib.mdDoc '' - The context path, i.e., the last part of the slskd - URL. Typically '/' or '/slskd'. Default '/' - ''; - }; - }; - }); + domain = mkOption { + type = types.nullOr types.str; + description = '' + If non-null, enables an nginx reverse proxy virtual host at this FQDN, + at the path configurated with `services.slskd.web.url_base`. + ''; + example = "slskd.example.com"; + }; + + nginx = mkOption { + type = types.submodule (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }); + default = {}; + example = lib.literalExpression '' + { + enableACME = true; + forceHttps = true; + } + ''; + description = '' + This option customizes the nginx virtual host set up for slskd. + ''; }; environmentFile = mkOption { type = path; description = '' - Path to a file containing secrets. - It must at least contain the variable `SLSKD_SLSK_PASSWORD` + Path to the environment file sourced on startup. + It must at least contain the variables `SLSKD_SLSK_USERNAME` and `SLSKD_SLSK_PASSWORD`. + Web interface credentials should also be set here in `SLSKD_USERNAME` and `SLSKD_PASSWORD`. + Other, optional credentials like SOCKS5 with `SLSKD_SLSK_PROXY_USERNAME` and `SLSKD_SLSK_PROXY_PASSWORD` + should all reside here instead of in the world-readable nix store. + Variables are documented at https://github.com/slskd/slskd/blob/master/docs/config.md ''; }; openFirewall = mkOption { type = bool; - description = '' - Whether to open the firewall for services.slskd.settings.listen_port"; - ''; + description = "Whether to open the firewall for the soulseek network listen port (not the web interface port)."; default = false; }; settings = mkOption { - description = lib.mdDoc '' - Configuration for slskd, see - [available options](https://github.com/slskd/slskd/blob/master/docs/config.md) - `APP_DIR` is set to /var/lib/slskd, where default download & incomplete directories, - log and databases will be created. + description = '' + Application configuration for slskd. See + [documentation](https://github.com/slskd/slskd/blob/master/docs/config.md). ''; default = {}; type = submodule { freeformType = settingsFormat.type; options = { + remote_file_management = mkEnableOption "modification of share contents through the web ui"; + + flags = { + force_share_scan = mkOption { + type = bool; + description = "Force a rescan of shares on every startup."; + }; + no_version_check = mkOption { + type = bool; + default = true; + visible = false; + description = "Don't perform a version check on startup."; + }; + }; + + directories = { + incomplete = mkOption { + type = nullOr path; + description = "Directory where incomplete downloading files are stored."; + defaultText = "/var/lib/slskd/incomplete"; + default = null; + }; + downloads = mkOption { + type = nullOr path; + description = "Directory where downloaded files are stored."; + defaultText = "/var/lib/slskd/downloads"; + default = null; + }; + }; + + shares = { + directories = mkOption { + type = listOf str; + description = '' + Paths to shared directories. See + [documentation](https://github.com/slskd/slskd/blob/master/docs/config.md#directories) + for advanced usage. + ''; + example = lib.literalExpression ''[ "/home/John/Music" "!/home/John/Music/Recordings" "[Music Drive]/mnt" ]''; + }; + filters = mkOption { + type = listOf str; + example = lib.literalExpression ''[ "\.ini$" "Thumbs.db$" "\.DS_Store$" ]''; + description = "Regular expressions of files to exclude from sharing."; + }; + }; + + rooms = mkOption { + type = listOf str; + description = "Chat rooms to join on startup."; + }; soulseek = { - username = mkOption { + description = mkOption { type = str; - description = "Username on the Soulseek Network"; + description = "The user description for the Soulseek network."; + defaultText = "A slskd user. https://github.com/slskd/slskd"; }; listen_port = mkOption { type = port; - description = "Port to use for communication on the Soulseek Network"; - default = 50000; + description = "The port on which to listen for incoming connections."; + default = 50300; }; }; + global = { + # TODO speed units + upload = { + slots = mkOption { + type = ints.unsigned; + description = "Limit of the number of concurrent upload slots."; + }; + speed_limit = mkOption { + type = ints.unsigned; + description = "Total upload speed limit."; + }; + }; + download = { + slots = mkOption { + type = ints.unsigned; + description = "Limit of the number of concurrent download slots."; + }; + speed_limit = mkOption { + type = ints.unsigned; + description = "Total upload download limit"; + }; + }; + }; + + filters.search.request = mkOption { + type = listOf str; + example = lib.literalExpression ''[ "^.{1,2}$" ]''; + description = "Incoming search requests which match this filter are ignored."; + }; + web = { port = mkOption { type = port; - default = 5001; - description = "The HTTP listen port"; + default = 5030; + description = "The HTTP listen port."; }; url_base = mkOption { type = path; - default = config.services.slskd.nginx.contextPath; - defaultText = "config.services.slskd.nginx.contextPath"; - description = lib.mdDoc '' - The context path, i.e., the last part of the slskd URL - ''; + default = "/"; + description = "The base path in the url for web requests."; + }; + # Users should use a reverse proxy instead for https + https.disabled = mkOption { + type = bool; + default = true; + description = "Disable the built-in HTTPS server"; }; }; - shares = { - directories = mkOption { - type = listOf str; - description = lib.mdDoc '' - Paths to your shared directories. See - [documentation](https://github.com/slskd/slskd/blob/master/docs/config.md#directories) - for advanced usage - ''; + retention = { + transfers = { + upload = { + succeeded = mkOption { + type = ints.unsigned; + description = "Lifespan of succeeded upload tasks."; + defaultText = "(indefinite)"; + }; + errored = mkOption { + type = ints.unsigned; + description = "Lifespan of errored upload tasks."; + defaultText = "(indefinite)"; + }; + cancelled = mkOption { + type = ints.unsigned; + description = "Lifespan of cancelled upload tasks."; + defaultText = "(indefinite)"; + }; + }; + download = { + succeeded = mkOption { + type = ints.unsigned; + description = "Lifespan of succeeded download tasks."; + defaultText = "(indefinite)"; + }; + errored = mkOption { + type = ints.unsigned; + description = "Lifespan of errored download tasks."; + defaultText = "(indefinite)"; + }; + cancelled = mkOption { + type = ints.unsigned; + description = "Lifespan of cancelled download tasks."; + defaultText = "(indefinite)"; + }; + }; + }; + files = { + complete = mkOption { + type = ints.unsigned; + description = "Lifespan of completely downloaded files in minutes."; + example = 20160; + defaultText = "(indefinite)"; + }; + incomplete = mkOption { + type = ints.unsigned; + description = "Lifespan of incomplete downloading files in minutes."; + defaultText = "(indefinite)"; + }; }; }; - directories = { - incomplete = mkOption { - type = nullOr path; - description = "Directory where downloading files are stored"; - defaultText = "<APP_DIR>/incomplete"; - default = null; - }; - downloads = mkOption { - type = nullOr path; - description = "Directory where downloaded files are stored"; - defaultText = "<APP_DIR>/downloads"; - default = null; + logger = { + # Disable by default, journald already retains as needed + disk = mkOption { + type = bool; + description = "Whether to log to the application directory."; + default = false; + visible = false; }; }; }; @@ -126,51 +254,42 @@ in { config = let cfg = config.services.slskd; - confWithoutNullValues = (lib.filterAttrs (key: value: value != null) cfg.settings); + confWithoutNullValues = (lib.filterAttrsRecursive (key: value: (builtins.tryEval value).success && value != null) cfg.settings); configurationYaml = settingsFormat.generate "slskd.yml" confWithoutNullValues; in lib.mkIf cfg.enable { - users = { - users.slskd = { + # Force off, configuration file is in nix store and is immutable + services.slskd.settings.remote_configuration = lib.mkForce false; + + users.users = lib.optionalAttrs (cfg.user == defaultUser) { + "${defaultUser}" = { + group = cfg.group; isSystemUser = true; - group = "slskd"; }; - groups.slskd = {}; }; - # Reverse proxy configuration - services.nginx.enable = true; - services.nginx.virtualHosts."${cfg.nginx.domainName}" = { - forceSSL = true; - enableACME = true; - locations = { - "${cfg.nginx.contextPath}" = { - proxyPass = "http://localhost:${toString cfg.settings.web.port}"; - proxyWebsockets = true; - }; - }; + users.groups = lib.optionalAttrs (cfg.group == defaultUser) { + "${defaultUser}" = {}; }; - # Hide state & logs - systemd.tmpfiles.rules = [ - "d /var/lib/slskd/data 0750 slskd slskd - -" - "d /var/lib/slskd/logs 0750 slskd slskd - -" - ]; - systemd.services.slskd = { description = "A modern client-server application for the Soulseek file sharing network"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; - User = "slskd"; + User = cfg.user; + Group = cfg.group; EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; - StateDirectory = "slskd"; + StateDirectory = "slskd"; # Creates /var/lib/slskd and manages permissions ExecStart = "${cfg.package}/bin/slskd --app-dir /var/lib/slskd --config ${configurationYaml}"; Restart = "on-failure"; ReadOnlyPaths = map (d: builtins.elemAt (builtins.split "[^/]*(/.+)" d) 1) cfg.settings.shares.directories; + ReadWritePaths = + (lib.optional (cfg.settings.directories.incomplete != null) cfg.settings.directories.incomplete) ++ + (lib.optional (cfg.settings.directories.downloads != null) cfg.settings.directories.downloads); LockPersonality = true; NoNewPrivileges = true; PrivateDevices = true; @@ -194,18 +313,21 @@ in { networking.firewall.allowedTCPPorts = lib.optional cfg.openFirewall cfg.settings.soulseek.listen_port; - systemd.services.slskd-rotatelogs = lib.mkIf cfg.rotateLogs { - description = "Rotate slskd logs"; - serviceConfig = { - Type = "oneshot"; - User = "slskd"; - ExecStart = [ - "${pkgs.findutils}/bin/find /var/lib/slskd/logs/ -type f -mtime +10 -delete" - "${pkgs.findutils}/bin/find /var/lib/slskd/logs/ -type f -mtime +1 -exec ${pkgs.gzip}/bin/gzip -q {} ';'" - ]; - }; - startAt = "daily"; + services.nginx = lib.mkIf (cfg.domain != null) { + enable = lib.mkDefault true; + virtualHosts."${cfg.domain}" = lib.mkMerge [ + cfg.nginx + { + locations."${cfg.settings.web.url_base}" = { + proxyPass = "http://127.0.0.1:${toString cfg.settings.web.port}"; + proxyWebsockets = true; + }; + } + ]; }; + }; + meta = { + maintainers = with lib.maintainers; [ ppom melvyn2 ]; }; } diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 4e0235f9ad1dd..453f414e2a862 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -303,7 +303,7 @@ in type = types.listOf types.str; default = [ "modesetting" "fbdev" ]; example = [ - "nvidia" "nvidiaLegacy390" "nvidiaLegacy340" "nvidiaLegacy304" + "nvidia" "amdgpu-pro" ]; # TODO(@oxij): think how to easily add the rest, like those nvidia things diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix index da7873c7bec86..a89d000ed299b 100644 --- a/nixos/modules/virtualisation/incus.nix +++ b/nixos/modules/virtualisation/incus.nix @@ -1,8 +1,80 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: let cfg = config.virtualisation.incus; preseedFormat = pkgs.formats.yaml { }; + + serverBinPath = ''${pkgs.qemu_kvm}/libexec:${ + lib.makeBinPath ( + with pkgs; + [ + cfg.package + + acl + attr + bash + btrfs-progs + cdrkit + coreutils + criu + dnsmasq + e2fsprogs + findutils + getent + gnugrep + gnused + gnutar + gptfdisk + gzip + iproute2 + iptables + kmod + lvm2 + minio + nftables + qemu_kvm + qemu-utils + rsync + squashfsTools + systemd + thin-provisioning-tools + util-linux + virtiofsd + xz + + (writeShellScriptBin "apparmor_parser" '' + exec '${apparmor-parser}/bin/apparmor_parser' -I '${apparmor-profiles}/etc/apparmor.d' "$@" + '') + ] + ++ lib.optionals config.boot.zfs.enabled [ + config.boot.zfs.package + "${config.boot.zfs.package}/lib/udev" + ] + ++ lib.optionals config.virtualisation.vswitch.enable [ config.virtualisation.vswitch.package ] + ) + }''; + + # https://github.com/lxc/incus/blob/cff35a29ee3d7a2af1f937cbb6cf23776941854b/internal/server/instance/drivers/driver_qemu.go#L123 + ovmf-prefix = if pkgs.stdenv.hostPlatform.isAarch64 then "AAVMF" else "OVMF"; + ovmf = pkgs.linkFarm "incus-ovmf" [ + { + name = "OVMF_CODE.4MB.fd"; + path = "${pkgs.OVMFFull.fd}/FV/${ovmf-prefix}_CODE.fd"; + } + { + name = "OVMF_VARS.4MB.fd"; + path = "${pkgs.OVMFFull.fd}/FV/${ovmf-prefix}_VARS.fd"; + } + { + name = "OVMF_VARS.4MB.ms.fd"; + path = "${pkgs.OVMFFull.fd}/FV/${ovmf-prefix}_VARS.fd"; + } + ]; in { meta = { @@ -11,26 +83,29 @@ in options = { virtualisation.incus = { - enable = lib.mkEnableOption (lib.mdDoc '' + enable = lib.mkEnableOption '' incusd, a daemon that manages containers and virtual machines. Users in the "incus-admin" group can interact with the daemon (e.g. to start or stop containers) using the {command}`incus` command line tool, among others. - ''); + ''; package = lib.mkPackageOption pkgs "incus" { }; lxcPackage = lib.mkPackageOption pkgs "lxc" { }; + clientPackage = lib.mkPackageOption pkgs [ + "incus" + "client" + ] { }; + preseed = lib.mkOption { - type = lib.types.nullOr ( - lib.types.submodule { freeformType = preseedFormat.type; } - ); + type = lib.types.nullOr (lib.types.submodule { freeformType = preseedFormat.type; }); default = null; - description = lib.mdDoc '' + description = '' Configuration for Incus preseed, see <https://linuxcontainers.org/incus/docs/main/howto/initialize/#non-interactive-configuration> for supported values. @@ -80,18 +155,16 @@ in }; }; - socketActivation = lib.mkEnableOption ( - lib.mdDoc '' - socket-activation for starting incus.service. Enabling this option - will stop incus.service from starting automatically on boot. - '' - ); + socketActivation = lib.mkEnableOption ('' + socket-activation for starting incus.service. Enabling this option + will stop incus.service from starting automatically on boot. + ''); startTimeout = lib.mkOption { type = lib.types.ints.unsigned; default = 600; apply = toString; - description = lib.mdDoc '' + description = '' Time to wait (in seconds) for incusd to become ready to process requests. If incusd does not reply within the configured time, `incus.service` will be considered failed and systemd will attempt to restart it. @@ -99,9 +172,12 @@ in }; ui = { - enable = lib.mkEnableOption (lib.mdDoc "(experimental) Incus UI"); + enable = lib.mkEnableOption "(experimental) Incus UI"; - package = lib.mkPackageOption pkgs [ "incus" "ui" ] { }; + package = lib.mkPackageOption pkgs [ + "incus" + "ui" + ] { }; }; }; }; @@ -109,7 +185,12 @@ in config = lib.mkIf cfg.enable { assertions = [ { - assertion = !(config.networking.firewall.enable && !config.networking.nftables.enable && config.virtualisation.incus.enable); + assertion = + !( + config.networking.firewall.enable + && !config.networking.nftables.enable + && config.virtualisation.incus.enable + ); message = "Incus on NixOS is unsupported using iptables. Set `networking.nftables.enable = true;`"; } ]; @@ -137,7 +218,12 @@ in "vhost_vsock" ] ++ lib.optionals (!config.networking.nftables.enable) [ "iptable_mangle" ]; - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ + cfg.clientPackage + + # gui console support + pkgs.spice-gtk + ]; # Note: the following options are also declared in virtualisation.lxc, but # the latter can't be simply enabled to reuse the formers, because it @@ -164,31 +250,23 @@ in "network-online.target" "lxcfs.service" "incus.socket" - ] - ++ lib.optional config.virtualisation.vswitch.enable "ovs-vswitchd.service"; + ] ++ lib.optionals config.virtualisation.vswitch.enable [ "ovs-vswitchd.service" ]; requires = [ "lxcfs.service" "incus.socket" - ] - ++ lib.optional config.virtualisation.vswitch.enable "ovs-vswitchd.service"; - - wants = [ - "network-online.target" - ]; + ] ++ lib.optionals config.virtualisation.vswitch.enable [ "ovs-vswitchd.service" ]; - path = lib.optionals config.boot.zfs.enabled [ - config.boot.zfs.package - "${config.boot.zfs.package}/lib/udev" - ] - ++ lib.optional config.virtualisation.vswitch.enable config.virtualisation.vswitch.package; + wants = [ "network-online.target" ]; - environment = lib.mkMerge [ { - # Override Path to the LXC template configuration directory - INCUS_LXC_TEMPLATE_CONFIG = "${pkgs.lxcfs}/share/lxc/config"; - } (lib.mkIf (cfg.ui.enable) { - "INCUS_UI" = cfg.ui.package; - }) ]; + environment = lib.mkMerge [ + { + INCUS_LXC_TEMPLATE_CONFIG = "${pkgs.lxcfs}/share/lxc/config"; + INCUS_OVMF_PATH = ovmf; + PATH = lib.mkForce serverBinPath; + } + (lib.mkIf (cfg.ui.enable) { "INCUS_UI" = cfg.ui.package; }) + ]; serviceConfig = { ExecStart = "${cfg.package}/bin/incusd --group incus-admin"; @@ -222,15 +300,13 @@ in systemd.services.incus-preseed = lib.mkIf (cfg.preseed != null) { description = "Incus initialization with preseed file"; - wantedBy = ["incus.service"]; - after = ["incus.service"]; - bindsTo = ["incus.service"]; - partOf = ["incus.service"]; + wantedBy = [ "incus.service" ]; + after = [ "incus.service" ]; + bindsTo = [ "incus.service" ]; + partOf = [ "incus.service" ]; script = '' - ${cfg.package}/bin/incus admin init --preseed <${ - preseedFormat.generate "incus-preseed.yaml" cfg.preseed - } + ${cfg.package}/bin/incus admin init --preseed <${preseedFormat.generate "incus-preseed.yaml" cfg.preseed} ''; serviceConfig = { diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index d9e9108079322..69d340bae2774 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -309,6 +309,7 @@ in { firefox-devedition = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-devedition; }; firefox-esr = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-esr; }; # used in `tested` job firefox-esr-115 = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-esr-115; }; + firefoxpwa = handleTest ./firefoxpwa.nix {}; firejail = handleTest ./firejail.nix {}; firewall = handleTest ./firewall.nix { nftables = false; }; firewall-nftables = handleTest ./firewall.nix { nftables = true; }; diff --git a/nixos/tests/firefoxpwa.nix b/nixos/tests/firefoxpwa.nix new file mode 100644 index 0000000000000..374d67b01ac60 --- /dev/null +++ b/nixos/tests/firefoxpwa.nix @@ -0,0 +1,36 @@ +import ./make-test-python.nix ({ lib, ... }: + +{ + name = "firefoxpwa"; + meta.maintainers = with lib.maintainers; [ camillemndn ]; + + nodes.machine = + { pkgs, ... }: + { + imports = [ ./common/x11.nix ]; + environment.systemPackages = with pkgs; [ firefoxpwa jq ]; + + programs.firefox = { + enable = true; + nativeMessagingHosts.packages = [ pkgs.firefoxpwa ]; + }; + + services.jellyfin.enable = true; + }; + + enableOCR = true; + + testScript = '' + machine.start() + + with subtest("Install a progressive web app"): + machine.wait_for_unit("jellyfin.service") + machine.wait_for_open_port(8096) + machine.succeed("firefoxpwa site install http://localhost:8096/web/manifest.json >&2") + + with subtest("Launch the progressive web app"): + machine.succeed("firefoxpwa site launch $(jq -r < ~/.local/share/firefoxpwa/config.json '.sites | keys[0]') >&2") + machine.wait_for_window("Jellyfin") + machine.wait_for_text("Jellyfin") + ''; +}) diff --git a/nixos/tests/incus/container.nix b/nixos/tests/incus/container.nix index 9260f70da98c2..a71c5355046a5 100644 --- a/nixos/tests/incus/container.nix +++ b/nixos/tests/incus/container.nix @@ -1,20 +1,21 @@ -import ../make-test-python.nix ({ pkgs, lib, extra ? {}, ... } : +import ../make-test-python.nix ({ pkgs, lib, extra ? {}, name ? "incus-container", ... } : let releases = import ../../release.nix { - configuration = { - # Building documentation makes the test unnecessarily take a longer time: - documentation.enable = lib.mkForce false; + configuration = lib.recursiveUpdate { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; - boot.kernel.sysctl."net.ipv4.ip_forward" = "1"; - } // extra; + boot.kernel.sysctl."net.ipv4.ip_forward" = "1"; + } + extra; }; container-image-metadata = releases.lxdContainerMeta.${pkgs.stdenv.hostPlatform.system}; container-image-rootfs = releases.lxdContainerImage.${pkgs.stdenv.hostPlatform.system}; in { - name = "incus-container"; + inherit name; meta = { maintainers = lib.teams.lxc.members; diff --git a/nixos/tests/incus/default.nix b/nixos/tests/incus/default.nix index 32bc5396a1647..b850c4fba018d 100644 --- a/nixos/tests/incus/default.nix +++ b/nixos/tests/incus/default.nix @@ -5,16 +5,22 @@ handleTestOn, }: { - container-old-init = import ./container.nix { inherit system pkgs; }; - container-new-init = import ./container.nix { inherit system pkgs; extra = { - # Enable new systemd init - boot.initrd.systemd.enable = true; - }; }; + container-legacy-init = import ./container.nix { + name = "container-legacy-init"; + inherit system pkgs; + }; + container-systemd-init = import ./container.nix { + name = "container-systemd-init"; + inherit system pkgs; + extra = { + boot.initrd.systemd.enable = true; + }; + }; lxd-to-incus = import ./lxd-to-incus.nix { inherit system pkgs; }; openvswitch = import ./openvswitch.nix { inherit system pkgs; }; preseed = import ./preseed.nix { inherit system pkgs; }; socket-activated = import ./socket-activated.nix { inherit system pkgs; }; storage = import ./storage.nix { inherit system pkgs; }; - ui = import ./ui.nix {inherit system pkgs;}; + ui = import ./ui.nix { inherit system pkgs; }; virtual-machine = handleTestOn [ "x86_64-linux" ] ./virtual-machine.nix { inherit system pkgs; }; } diff --git a/nixos/tests/incus/lxd-to-incus.nix b/nixos/tests/incus/lxd-to-incus.nix index 262f63c0f26fb..e93b76591eca4 100644 --- a/nixos/tests/incus/lxd-to-incus.nix +++ b/nixos/tests/incus/lxd-to-incus.nix @@ -95,7 +95,7 @@ import ../make-test-python.nix ( machine.wait_for_unit("incus.service") with machine.nested("run migration"): - machine.succeed("lxd-to-incus --yes") + machine.succeed("${pkgs.incus}/bin/lxd-to-incus --yes") with machine.nested("verify resources migrated to incus"): machine.succeed("incus config show container") diff --git a/nixos/tests/tracee.nix b/nixos/tests/tracee.nix index 3dadc0f9fdb33..1c241f3ec4983 100644 --- a/nixos/tests/tracee.nix +++ b/nixos/tests/tracee.nix @@ -1,7 +1,13 @@ -import ./make-test-python.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: rec { name = "tracee-integration"; meta.maintainers = pkgs.tracee.meta.maintainers; + passthru.hello-world-builder = pkgs: pkgs.dockerTools.buildImage { + name = "hello-world"; + tag = "latest"; + config.Cmd = [ "${pkgs.hello}/bin/hello" ]; + }; + nodes = { machine = { config, pkgs, ... }: { # EventFilters/trace_only_events_from_new_containers and @@ -12,57 +18,48 @@ import ./make-test-python.nix ({ pkgs, ... }: { environment.systemPackages = with pkgs; [ # required by Test_EventFilters/trace_events_from_ls_and_which_binary_in_separate_scopes which - # build the go integration tests as a binary - (tracee.overrideAttrs (oa: { - pname = oa.pname + "-integration"; - postPatch = oa.postPatch or "" + '' - # prepare tester.sh (which will be embedded in the test binary) - patchShebangs tests/integration/tester.sh - - # fix the test to look at nixos paths for running programs - substituteInPlace tests/integration/integration_test.go \ - --replace "bin=/usr/bin/" "comm=" \ - --replace "binary=/usr/bin/" "comm=" \ - --replace "/usr/bin/dockerd" "dockerd" \ - --replace "/usr/bin" "/run/current-system/sw/bin" - ''; - nativeBuildInputs = oa.nativeBuildInputs or [ ] ++ [ makeWrapper ]; - buildPhase = '' - runHook preBuild - # just build the static lib we need for the go test binary - make $makeFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES} bpf-core ./dist/btfhub - - # then compile the tests to be ran later - CGO_LDFLAGS="$(pkg-config --libs libbpf)" go test -tags core,ebpf,integration -p 1 -c -o $GOPATH/tracee-integration ./tests/integration/... - runHook postBuild - ''; - doCheck = false; - outputs = [ "out" ]; - installPhase = '' - mkdir -p $out/bin - mv $GOPATH/tracee-integration $out/bin/ - ''; - doInstallCheck = false; - - meta = oa.meta // { - outputsToInstall = []; - }; - })) + # the go integration tests as a binary + tracee.passthru.tests.integration-test-cli ]; }; }; - testScript = '' - machine.wait_for_unit("docker.service") + testScript = + let + skippedTests = [ + # these comm tests for some reason do not resolve. + # something about the test is different as it works fine if I replicate + # the policies and run tracee myself but doesn't work in the integration + # test either with the automatic run or running the commands by hand + # while it's searching. + "Test_EventFilters/comm:_event:_args:_trace_event_set_in_a_specific_policy_with_args_from_ls_command" + "Test_EventFilters/comm:_event:_trace_events_set_in_two_specific_policies_from_ls_and_uname_commands" + + # worked at some point, seems to be flakey + "Test_EventFilters/pid:_event:_args:_trace_event_sched_switch_with_args_from_pid_0" + ]; + in + '' + with subtest("prepare for integration tests"): + machine.wait_for_unit("docker.service") + machine.succeed('which bash') + + # EventFilters/trace_only_events_from_new_containers also requires a container called "hello-world" + machine.succeed('docker load < ${passthru.hello-world-builder pkgs}') - with subtest("run integration tests"): - # EventFilters/trace_only_events_from_new_containers also requires a container called "alpine" - machine.succeed('tar c -C ${pkgs.pkgsStatic.busybox} . | docker import - alpine --change "ENTRYPOINT [\"sleep\"]"') + # exec= needs fully resolved paths + machine.succeed( + 'mkdir /tmp/testdir', + 'cp $(which who) /tmp/testdir/who', + 'cp $(which uname) /tmp/testdir/uname', + ) - # Test_EventFilters/trace_event_set_in_a_specific_scope expects to be in a dir that includes "integration" - print(machine.succeed( - 'mkdir /tmp/integration', - 'cd /tmp/integration && tracee-integration -test.v' - )) - ''; + with subtest("run integration tests"): + # Test_EventFilters/trace_event_set_in_a_specific_scope expects to be in a dir that includes "integration" + # tests must be ran with 1 process + print(machine.succeed( + 'mkdir /tmp/integration', + 'cd /tmp/integration && export PATH="/tmp/testdir:$PATH" && integration.test -test.v -test.parallel 1 -test.skip="^${builtins.concatStringsSep "$|^" skippedTests}$"' + )) + ''; }) |