From 1ed6468c276a295f5a336f126ef695ab25f58acb Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 5 May 2023 21:00:50 +0200 Subject: nixos.tinyproxy: init --- nixos/modules/module-list.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4e0a44c4092..f3bd8c9d438 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1034,6 +1034,7 @@ ./services/networking/thelounge.nix ./services/networking/tinc.nix ./services/networking/tinydns.nix + ./services/networking/tinyproxy.nix ./services/networking/tmate-ssh-server.nix ./services/networking/tox-bootstrapd.nix ./services/networking/tox-node.nix -- cgit 1.4.1 From cf6e43a3dd32d1fce0a315afd365aa90ee19130d Mon Sep 17 00:00:00 2001 From: misuzu Date: Fri, 7 Apr 2023 15:59:08 +0300 Subject: nixos/castopod: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/audio/castopod.md | 22 ++ nixos/modules/services/audio/castopod.nix | 287 ++++++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 nixos/modules/services/audio/castopod.md create mode 100644 nixos/modules/services/audio/castopod.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index af5147e0128..b03c7ad7ed6 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -41,6 +41,8 @@ - [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable). +- [Castopod](https://castopod.org/), an open-source hosting platform made for podcasters who want to engage and interact with their audience. Available as [services.castopod](#opt-services.castopod.enable). + - [Typesense](https://github.com/typesense/typesense), a fast, typo-tolerant search engine for building delightful search experiences. Available as [services.typesense](#opt-services.typesense.enable). * [NS-USBLoader](https://github.com/developersu/ns-usbloader/), an all-in-one tool for managing Nintendo Switch homebrew. Available as [programs.ns-usbloader](#opt-programs.ns-usbloader.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 206d5eaf75d..54fd5c7b040 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -324,6 +324,7 @@ ./services/amqp/rabbitmq.nix ./services/audio/alsa.nix ./services/audio/botamusique.nix + ./services/audio/castopod.nix ./services/audio/gmediarender.nix ./services/audio/gonic.nix ./services/audio/goxlr-utility.nix diff --git a/nixos/modules/services/audio/castopod.md b/nixos/modules/services/audio/castopod.md new file mode 100644 index 00000000000..ee8590737a7 --- /dev/null +++ b/nixos/modules/services/audio/castopod.md @@ -0,0 +1,22 @@ +# Castopod {#module-services-castopod} + +Castopod is an open-source hosting platform made for podcasters who want to engage and interact with their audience. + +## Quickstart {#module-services-castopod-quickstart} + +Use the following configuration to start a public instance of Castopod on `castopod.example.com` domain: + +```nix +networking.firewall.allowedTCPPorts = [ 80 443 ]; +services.castopod = { + enable = true; + database.createLocally = true; + nginx.virtualHost = { + serverName = "castopod.example.com"; + enableACME = true; + forceSSL = true; + }; +}; +``` + +Go to `https://castopod.example.com/cp-install` to create superadmin account after applying the above configuration. diff --git a/nixos/modules/services/audio/castopod.nix b/nixos/modules/services/audio/castopod.nix new file mode 100644 index 00000000000..b782b548914 --- /dev/null +++ b/nixos/modules/services/audio/castopod.nix @@ -0,0 +1,287 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.castopod; + fpm = config.services.phpfpm.pools.castopod; + + user = "castopod"; + stateDirectory = "/var/lib/castopod"; + + # https://docs.castopod.org/getting-started/install.html#requirements + phpPackage = pkgs.php.withExtensions ({ enabled, all }: with all; [ + intl + curl + mbstring + gd + exif + mysqlnd + ] ++ enabled); +in +{ + meta.doc = ./castopod.md; + meta.maintainers = with lib.maintainers; [ alexoundos misuzu ]; + + options.services = { + castopod = { + enable = lib.mkEnableOption (lib.mdDoc "Castopod"); + package = lib.mkOption { + type = lib.types.package; + default = pkgs.castopod; + defaultText = lib.literalMD "pkgs.castopod"; + description = lib.mdDoc "Which Castopod package to use."; + }; + database = { + createLocally = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc '' + Create the database and database user locally. + ''; + }; + hostname = lib.mkOption { + type = lib.types.str; + default = "localhost"; + description = lib.mdDoc "Database hostname."; + }; + name = lib.mkOption { + type = lib.types.str; + default = "castopod"; + description = lib.mdDoc "Database name."; + }; + user = lib.mkOption { + type = lib.types.str; + default = user; + description = lib.mdDoc "Database user."; + }; + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/keys/castopod-dbpassword"; + description = lib.mdDoc '' + A file containing the password corresponding to + [](#opt-services.castopod.database.user). + ''; + }; + }; + settings = lib.mkOption { + type = with lib.types; attrsOf (oneOf [ str int bool ]); + default = { }; + example = { + "email.protocol" = "smtp"; + "email.SMTPHost" = "localhost"; + "email.SMTPUser" = "myuser"; + "email.fromEmail" = "castopod@example.com"; + }; + description = lib.mdDoc '' + Environment variables used for Castopod. + See [](https://code.castopod.org/adaures/castopod/-/blob/main/.env.example) + for available environment variables. + ''; + }; + environmentFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/keys/castopod-env"; + description = lib.mdDoc '' + Environment file to inject e.g. secrets into the configuration. + See [](https://code.castopod.org/adaures/castopod/-/blob/main/.env.example) + for available environment variables. + ''; + }; + configureNginx = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc "Configure nginx as a reverse proxy for CastoPod."; + }; + localDomain = lib.mkOption { + type = lib.types.str; + example = "castopod.example.org"; + description = lib.mdDoc "The domain serving your CastoPod instance."; + }; + poolSettings = lib.mkOption { + type = with lib.types; attrsOf (oneOf [ str int bool ]); + default = { + "pm" = "dynamic"; + "pm.max_children" = "32"; + "pm.start_servers" = "2"; + "pm.min_spare_servers" = "2"; + "pm.max_spare_servers" = "4"; + "pm.max_requests" = "500"; + }; + description = lib.mdDoc '' + Options for Castopod's PHP pool. See the documentation on `php-fpm.conf` for details on configuration directives. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + services.castopod.settings = + let + sslEnabled = with config.services.nginx.virtualHosts.${cfg.localDomain}; addSSL || forceSSL || onlySSL || enableACME || useACMEHost != null; + baseURL = "http${lib.optionalString sslEnabled "s"}://${cfg.localDomain}"; + in + lib.mapAttrs (name: lib.mkDefault) { + "app.forceGlobalSecureRequests" = sslEnabled; + "app.baseURL" = baseURL; + + "media.baseURL" = "/"; + "media.root" = "media"; + "media.storage" = stateDirectory; + + "admin.gateway" = "admin"; + "auth.gateway" = "auth"; + + "database.default.hostname" = cfg.database.hostname; + "database.default.database" = cfg.database.name; + "database.default.username" = cfg.database.user; + "database.default.DBPrefix" = "cp_"; + + "cache.handler" = "file"; + }; + + services.phpfpm.pools.castopod = { + inherit user; + group = config.services.nginx.group; + phpPackage = phpPackage; + phpOptions = '' + # https://code.castopod.org/adaures/castopod/-/blob/main/docker/production/app/uploads.ini + file_uploads = On + memory_limit = 512M + upload_max_filesize = 500M + post_max_size = 512M + max_execution_time = 300 + max_input_time = 300 + ''; + settings = { + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; + } // cfg.poolSettings; + }; + + systemd.services.castopod-setup = { + after = lib.optional config.services.mysql.enable "mysql.service"; + requires = lib.optional config.services.mysql.enable "mysql.service"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.openssl phpPackage ]; + script = + let + envFile = "${stateDirectory}/.env"; + media = "${cfg.settings."media.storage"}/${cfg.settings."media.root"}"; + in + '' + mkdir -p ${stateDirectory}/writable/{cache,logs,session,temp,uploads} + + if [ ! -d ${lib.escapeShellArg media} ]; then + cp --no-preserve=mode,ownership -r ${cfg.package}/share/castopod/public/media ${lib.escapeShellArg media} + fi + + if [ ! -f ${stateDirectory}/salt ]; then + openssl rand -base64 33 > ${stateDirectory}/salt + fi + + cat <<'EOF' > ${envFile} + ${lib.generators.toKeyValue { } cfg.settings} + EOF + + echo "analytics.salt=$(cat ${stateDirectory}/salt)" >> ${envFile} + + ${if (cfg.database.passwordFile != null) then '' + echo "database.default.password=$(cat ${lib.escapeShellArg cfg.database.passwordFile})" >> ${envFile} + '' else '' + echo "database.default.password=" >> ${envFile} + ''} + + ${lib.optionalString (cfg.environmentFile != null) '' + cat ${lib.escapeShellArg cfg.environmentFile}) >> ${envFile} + ''} + + php spark castopod:database-update + ''; + serviceConfig = { + StateDirectory = "castopod"; + WorkingDirectory = "${cfg.package}/share/castopod"; + Type = "oneshot"; + RemainAfterExit = true; + User = user; + Group = config.services.nginx.group; + }; + }; + + systemd.services.castopod-scheduled = { + after = [ "castopod-setup.service" ]; + wantedBy = [ "multi-user.target" ]; + path = [ phpPackage ]; + script = '' + php public/index.php scheduled-activities + php public/index.php scheduled-websub-publish + php public/index.php scheduled-video-clips + ''; + serviceConfig = { + StateDirectory = "castopod"; + WorkingDirectory = "${cfg.package}/share/castopod"; + Type = "oneshot"; + User = user; + Group = config.services.nginx.group; + }; + }; + + systemd.timers.castopod-scheduled = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "*-*-* *:*:00"; + Unit = "castopod-scheduled.service"; + }; + }; + + services.mysql = lib.mkIf cfg.database.createLocally { + enable = true; + package = lib.mkDefault pkgs.mariadb; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [{ + name = cfg.database.user; + ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }; + }]; + }; + + services.nginx = lib.mkIf cfg.configureNginx { + enable = true; + virtualHosts."${cfg.localDomain}" = { + root = lib.mkForce "${cfg.package}/share/castopod/public"; + + extraConfig = '' + try_files $uri $uri/ /index.php?$args; + index index.php index.html; + ''; + + locations."^~ /${cfg.settings."media.root"}/" = { + root = cfg.settings."media.storage"; + extraConfig = '' + add_header Access-Control-Allow-Origin "*"; + expires max; + access_log off; + ''; + }; + + locations."~ \.php$" = { + fastcgiParams = { + SERVER_NAME = "$host"; + }; + extraConfig = '' + fastcgi_intercept_errors on; + fastcgi_index index.php; + fastcgi_pass unix:${fpm.socket}; + try_files $uri =404; + fastcgi_read_timeout 3600; + fastcgi_send_timeout 3600; + ''; + }; + }; + }; + + users.users.${user} = lib.mapAttrs (name: lib.mkDefault) { + description = "Castopod user"; + isSystemUser = true; + group = config.services.nginx.group; + }; + }; +} -- cgit 1.4.1 From 01cc0a605a03e0d6ad0b3482c964a67c3fdff01d Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Tue, 26 Sep 2023 23:27:22 +0200 Subject: nixos/tuxedo-rs: init at 0.2.2 --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/hardware/tuxedo-rs.nix | 49 +++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 nixos/modules/services/hardware/tuxedo-rs.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index cdb73fb49fa..5a955a209e0 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -80,6 +80,8 @@ - [NNCP](http://www.nncpgo.org/). Added nncp-daemon and nncp-caller services. Configuration is set with [programs.nncp.settings](#opt-programs.nncp.settings) and the daemons are enabled at [services.nncp](#opt-services.nncp.caller.enable). +- [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers. + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 54fd5c7b040..cbd5e6467f8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -541,6 +541,7 @@ ./services/hardware/tlp.nix ./services/hardware/trezord.nix ./services/hardware/triggerhappy.nix + ./services/hardware/tuxedo-rs.nix ./services/hardware/udev.nix ./services/hardware/udisks2.nix ./services/hardware/undervolt.nix diff --git a/nixos/modules/services/hardware/tuxedo-rs.nix b/nixos/modules/services/hardware/tuxedo-rs.nix new file mode 100644 index 00000000000..343f6845fab --- /dev/null +++ b/nixos/modules/services/hardware/tuxedo-rs.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.hardware.tuxedo-rs; + +in +{ + options = { + hardware.tuxedo-rs = { + enable = mkEnableOption (lib.mdDoc "Rust utilities for interacting with hardware from TUXEDO Computers."); + + tailor-gui.enable = mkEnableOption (lib.mdDoc "Alternative to TUXEDO Control Center, written in Rust."); + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { + hardware.tuxedo-keyboard.enable = true; + + systemd = { + services.tailord = { + enable = true; + description = "Tuxedo Tailor hardware control service"; + after = [ "systemd-logind.service" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "dbus"; + BusName = "com.tux.Tailor"; + ExecStart = "${pkgs.tuxedo-rs}/bin/tailord"; + Environment = "RUST_BACKTRACE=1"; + Restart = "on-failure"; + }; + }; + }; + + services.dbus.packages = [ pkgs.tuxedo-rs ]; + + environment.systemPackages = [ pkgs.tuxedo-rs ]; + } + (mkIf cfg.tailor-gui.enable { + environment.systemPackages = [ pkgs.tailor-gui ]; + }) + ]); + + meta.maintainers = with maintainers; [ mrcjkb ]; +} -- cgit 1.4.1 From f857cfd5bee8e5f10f7361cdcb032ba04aee8d54 Mon Sep 17 00:00:00 2001 From: Quantenzitrone Date: Wed, 13 Sep 2023 14:06:11 +0200 Subject: rimgo: add module --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/rimgo.nix | 107 ++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 nixos/modules/services/web-apps/rimgo.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cbd5e6467f8..9826866a9c3 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1284,6 +1284,7 @@ ./services/web-apps/powerdns-admin.nix ./services/web-apps/prosody-filer.nix ./services/web-apps/restya-board.nix + ./services/web-apps/rimgo.nix ./services/web-apps/sftpgo.nix ./services/web-apps/rss-bridge.nix ./services/web-apps/selfoss.nix diff --git a/nixos/modules/services/web-apps/rimgo.nix b/nixos/modules/services/web-apps/rimgo.nix new file mode 100644 index 00000000000..4d35473fda3 --- /dev/null +++ b/nixos/modules/services/web-apps/rimgo.nix @@ -0,0 +1,107 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.rimgo; + inherit (lib) + mkOption + mkEnableOption + mkPackageOption + mkDefault + mkIf + types + literalExpression + optionalString + getExe + mapAttrs + ; +in +{ + options.services.rimgo = { + enable = mkEnableOption "rimgo"; + package = mkPackageOption pkgs "rimgo" { }; + settings = mkOption { + type = types.submodule { + freeformType = with types; attrsOf str; + options = { + PORT = mkOption { + type = types.port; + default = 3000; + example = 69420; + description = "The port to use."; + }; + ADDRESS = mkOption { + type = types.str; + default = "127.0.0.1"; + example = "1.1.1.1"; + description = "The address to listen on."; + }; + }; + }; + example = literalExpression '' + { + PORT = 69420; + FORCE_WEBP = "1"; + } + ''; + description = '' + Settings for rimgo, see [the official documentation](https://rimgo.codeberg.page/docs/usage/configuration/) for supported options. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.rimgo = { + description = "Rimgo"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + environment = mapAttrs (_: toString) cfg.settings; + serviceConfig = { + ExecStart = getExe cfg.package; + AmbientCapabilities = mkIf (cfg.settings.PORT < 1024) [ + "CAP_NET_BIND_SERVICE" + ]; + DynamicUser = true; + Restart = "on-failure"; + RestartSec = "5s"; + CapabilityBoundingSet = [ + (optionalString (cfg.settings.PORT < 1024) "CAP_NET_BIND_SERVICE") + ]; + DeviceAllow = [ "" ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = cfg.settings.PORT >= 1024; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; + UMask = "0077"; + }; + }; + }; + + meta = { + maintainers = with lib.maintainers; [ quantenzitrone ]; + }; +} -- cgit 1.4.1 From 86dbce6d0788d602df543d08dfd9b692e69739e3 Mon Sep 17 00:00:00 2001 From: Wietse de Vries Date: Fri, 29 Sep 2023 11:46:13 +0200 Subject: audiobookshelf: init module --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/audiobookshelf.nix | 90 ++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/audiobookshelf.nix | 23 ++++++ 5 files changed, 117 insertions(+) create mode 100644 nixos/modules/services/web-apps/audiobookshelf.nix create mode 100644 nixos/tests/audiobookshelf.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index c6d479b8569..37b840539ea 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -87,6 +87,8 @@ - [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers. +- [audiobookshelf](https://github.com/advplyr/audiobookshelf/), a self-hosted audiobook and podcast server. Available as [services.audiobookshelf](#opt-services.audiobookshelf.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cbd5e6467f8..66782d04691 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1211,6 +1211,7 @@ ./services/web-apps/atlassian/confluence.nix ./services/web-apps/atlassian/crowd.nix ./services/web-apps/atlassian/jira.nix + ./services/web-apps/audiobookshelf.nix ./services/web-apps/bookstack.nix ./services/web-apps/calibre-web.nix ./services/web-apps/coder.nix diff --git a/nixos/modules/services/web-apps/audiobookshelf.nix b/nixos/modules/services/web-apps/audiobookshelf.nix new file mode 100644 index 00000000000..84dffc5f9d3 --- /dev/null +++ b/nixos/modules/services/web-apps/audiobookshelf.nix @@ -0,0 +1,90 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.audiobookshelf; +in +{ + options = { + services.audiobookshelf = { + enable = mkEnableOption "Audiobookshelf, self-hosted audiobook and podcast server."; + + package = mkPackageOption pkgs "audiobookshelf" { }; + + dataDir = mkOption { + description = "Path to Audiobookshelf config and metadata inside of /var/lib."; + default = "audiobookshelf"; + type = types.str; + }; + + host = mkOption { + description = "The host Audiobookshelf binds to."; + default = "127.0.0.1"; + example = "0.0.0.0"; + type = types.str; + }; + + port = mkOption { + description = "The TCP port Audiobookshelf will listen on."; + default = 8000; + type = types.port; + }; + + user = mkOption { + description = "User account under which Audiobookshelf runs."; + default = "audiobookshelf"; + type = types.str; + }; + + group = mkOption { + description = "Group under which Audiobookshelf runs."; + default = "audiobookshelf"; + type = types.str; + }; + + openFirewall = mkOption { + description = "Open ports in the firewall for the Audiobookshelf web interface."; + default = false; + type = types.bool; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.audiobookshelf = { + description = "Audiobookshelf is a self-hosted audiobook and podcast server"; + + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + StateDirectory = cfg.dataDir; + WorkingDirectory = "/var/lib/${cfg.dataDir}"; + ExecStart = "${cfg.package}/bin/audiobookshelf --host ${cfg.host} --port ${toString cfg.port}"; + Restart = "on-failure"; + }; + }; + + users.users = mkIf (cfg.user == "audiobookshelf") { + audiobookshelf = { + isSystemUser = true; + group = cfg.group; + home = "/var/lib/${cfg.dataDir}"; + }; + }; + + users.groups = mkIf (cfg.group == "audiobookshelf") { + audiobookshelf = { }; + }; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; + }; + + meta.maintainers = with maintainers; [ wietsedv ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 66a6aa252b8..5b2e12a501b 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -119,6 +119,7 @@ in { atd = handleTest ./atd.nix {}; atop = handleTest ./atop.nix {}; atuin = handleTest ./atuin.nix {}; + audiobookshelf = handleTest ./audiobookshelf.nix {}; auth-mysql = handleTest ./auth-mysql.nix {}; authelia = handleTest ./authelia.nix {}; avahi = handleTest ./avahi.nix {}; diff --git a/nixos/tests/audiobookshelf.nix b/nixos/tests/audiobookshelf.nix new file mode 100644 index 00000000000..64bd415160e --- /dev/null +++ b/nixos/tests/audiobookshelf.nix @@ -0,0 +1,23 @@ +import ./make-test-python.nix ({ lib, ... }: + +with lib; + +{ + name = "audiobookshelf"; + meta.maintainers = with maintainers; [ wietsedv ]; + + nodes.machine = + { pkgs, ... }: + { + services.audiobookshelf = { + enable = true; + port = 1234; + }; + }; + + testScript = '' + machine.wait_for_unit("audiobookshelf.service") + machine.wait_for_open_port(1234) + machine.succeed("curl --fail http://localhost:1234/") + ''; +}) -- cgit 1.4.1 From b571d96667fcb9d667b31e9f79c960a1da337c91 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 29 Sep 2023 23:07:34 +0200 Subject: nixos/wyoming/openwakeword: init The wyoming server for providing access to openWakeWord. --- nixos/modules/module-list.nix | 1 + .../services/audio/wyoming/openwakeword.nix | 157 +++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 nixos/modules/services/audio/wyoming/openwakeword.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 66782d04691..ec6f410a48f 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -346,6 +346,7 @@ ./services/audio/squeezelite.nix ./services/audio/tts.nix ./services/audio/wyoming/faster-whisper.nix + ./services/audio/wyoming/openwakeword.nix ./services/audio/wyoming/piper.nix ./services/audio/ympd.nix ./services/backup/automysqlbackup.nix diff --git a/nixos/modules/services/audio/wyoming/openwakeword.nix b/nixos/modules/services/audio/wyoming/openwakeword.nix new file mode 100644 index 00000000000..e1993407dad --- /dev/null +++ b/nixos/modules/services/audio/wyoming/openwakeword.nix @@ -0,0 +1,157 @@ +{ config +, lib +, pkgs +, ... +}: + +let + cfg = config.services.wyoming.openwakeword; + + inherit (lib) + concatMapStringsSep + escapeShellArgs + mkOption + mdDoc + mkEnableOption + mkIf + mkPackageOptionMD + types + ; + + inherit (builtins) + toString + ; + + models = [ + # wyoming_openwakeword/models/*.tflite + "alexa" + "hey_jarvis" + "hey_mycroft" + "hey_rhasspy" + "ok_nabu" + ]; + +in + +{ + meta.buildDocsInSandbox = false; + + options.services.wyoming.openwakeword = with types; { + enable = mkEnableOption (mdDoc "Wyoming openWakeWord server"); + + package = mkPackageOptionMD pkgs "wyoming-openwakeword" { }; + + uri = mkOption { + type = strMatching "^(tcp|unix)://.*$"; + default = "tcp://0.0.0.0:10400"; + example = "tcp://192.0.2.1:5000"; + description = mdDoc '' + URI to bind the wyoming server to. + ''; + }; + + models = mkOption { + type = listOf (enum models); + default = models; + description = mdDoc '' + List of wake word models that should be made available. + ''; + }; + + preloadModels = mkOption { + type = listOf (enum models); + default = [ + "ok_nabu" + ]; + description = mdDoc '' + List of wake word models to preload after startup. + ''; + }; + + threshold = mkOption { + type = float; + default = 0.5; + description = mdDoc '' + Activation threshold (0-1), where higher means fewer activations. + + See trigger level for the relationship between activations and + wake word detections. + ''; + apply = toString; + }; + + triggerLevel = mkOption { + type = int; + default = 1; + description = mdDoc '' + Number of activations before a detection is registered. + + A higher trigger level means fewer detections. + ''; + apply = toString; + }; + + extraArgs = mkOption { + type = listOf str; + default = [ ]; + description = mdDoc '' + Extra arguments to pass to the server commandline. + ''; + apply = escapeShellArgs; + }; + }; + + config = mkIf cfg.enable { + systemd.services."wyoming-openwakeword" = { + description = "Wyoming openWakeWord server"; + after = [ + "network-online.target" + ]; + wantedBy = [ + "multi-user.target" + ]; + serviceConfig = { + DynamicUser = true; + User = "wyoming-openwakeword"; + # https://github.com/home-assistant/addons/blob/master/openwakeword/rootfs/etc/s6-overlay/s6-rc.d/openwakeword/run + ExecStart = '' + ${cfg.package}/bin/wyoming-openwakeword \ + --uri ${cfg.uri} \ + ${concatMapStringsSep " " (model: "--model ${model}") cfg.models} \ + ${concatMapStringsSep " " (model: "--preload-model ${model}") cfg.preloadModels} \ + --threshold ${cfg.threshold} \ + --trigger-level ${cfg.triggerLevel} ${cfg.extraArgs} + ''; + CapabilityBoundingSet = ""; + DeviceAllow = ""; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RuntimeDirectory = "wyoming-openwakeword"; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; + UMask = "0077"; + }; + }; + }; +} -- cgit 1.4.1 From 638d19ac92232265a6e7031878ea35a0734c8def Mon Sep 17 00:00:00 2001 From: Ruby Juric Date: Tue, 3 Oct 2023 05:11:18 +0000 Subject: zitadel: init at 2.37.2; nixos/zitadel: init (#254896) --- maintainers/maintainer-list.nix | 10 + nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/zitadel.nix | 223 ++++++++++++++++++++++ pkgs/by-name/zi/zitadel/console.nix | 51 +++++ pkgs/by-name/zi/zitadel/package.json | 88 +++++++++ pkgs/by-name/zi/zitadel/package.nix | 150 +++++++++++++++ 7 files changed, 525 insertions(+) create mode 100644 nixos/modules/services/web-apps/zitadel.nix create mode 100644 pkgs/by-name/zi/zitadel/console.nix create mode 100644 pkgs/by-name/zi/zitadel/package.json create mode 100644 pkgs/by-name/zi/zitadel/package.nix (limited to 'nixos/modules/module-list.nix') diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 8b771a03a05..d3f781ccb80 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -16285,6 +16285,16 @@ githubId = 53029739; name = "Joshua Ortiz"; }; + Sorixelle = { + email = "ruby+nixpkgs@srxl.me"; + matrix = "@ruby:isincredibly.gay"; + name = "Ruby Iris Juric"; + github = "Sorixelle"; + githubId = 38685302; + keys = [{ + fingerprint = "2D76 76C7 A28E 16FC 75C7 268D 1B55 6ED8 4B0E 303A"; + }]; + }; sorki = { email = "srk@48.io"; github = "sorki"; diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index f235bca8e7c..b7d41f4b3f2 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -89,6 +89,8 @@ - [audiobookshelf](https://github.com/advplyr/audiobookshelf/), a self-hosted audiobook and podcast server. Available as [services.audiobookshelf](#opt-services.audiobookshelf.enable). +- [ZITADEL](https://zitadel.com), a turnkey identity and access management platform. Available as [services.zitadel](#opt-services.zitadel.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ec6f410a48f..4e2275cc661 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1302,6 +1302,7 @@ ./services/web-apps/writefreely.nix ./services/web-apps/youtrack.nix ./services/web-apps/zabbix.nix + ./services/web-apps/zitadel.nix ./services/web-servers/agate.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/caddy/default.nix diff --git a/nixos/modules/services/web-apps/zitadel.nix b/nixos/modules/services/web-apps/zitadel.nix new file mode 100644 index 00000000000..f225d138cc4 --- /dev/null +++ b/nixos/modules/services/web-apps/zitadel.nix @@ -0,0 +1,223 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.zitadel; + + settingsFormat = pkgs.formats.yaml { }; +in +{ + options.services.zitadel = + let inherit (lib) mkEnableOption mkOption mkPackageOption types; + in { + enable = mkEnableOption "ZITADEL, a user and identity access management platform."; + + package = mkPackageOption pkgs "ZITADEL" { default = [ "zitadel" ]; }; + + user = mkOption { + type = types.str; + default = "zitadel"; + description = "The user to run ZITADEL under."; + }; + + group = mkOption { + type = types.str; + default = "zitadel"; + description = "The group to run ZITADEL under."; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Whether to open the port specified in `listenPort` in the firewall. + ''; + }; + + masterKeyFile = mkOption { + type = types.path; + description = '' + Path to a file containing a master encryption key for ZITADEL. The + key must be 32 bytes. + ''; + }; + + tlsMode = mkOption { + type = types.enum [ "external" "enabled" "disabled" ]; + default = "external"; + example = "enabled"; + description = '' + The TLS mode to use. Options are: + + - enabled: ZITADEL accepts HTTPS connections directly. You must + configure TLS if this option is selected. + - external: ZITADEL forces HTTPS connections, with TLS terminated at a + reverse proxy. + - disabled: ZITADEL accepts HTTP connections only. Should only be used + for testing. + ''; + }; + + settings = mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + + options = { + Port = mkOption { + type = types.port; + default = 8080; + description = "The port that ZITADEL listens on."; + }; + + TLS = { + KeyPath = mkOption { + type = types.nullOr types.path; + default = null; + description = "Path to the TLS certificate private key."; + }; + Key = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The TLS certificate private key, as a base64-encoded string. + + Note that the contents of this option will be added to the Nix + store as world-readable plain text. Set + [KeyPath](#opt-services.zitadel.settings.TLS.KeyPath) instead + if this is undesired. + ''; + }; + CertPath = mkOption { + type = types.nullOr types.path; + default = null; + description = "Path to the TLS certificate."; + }; + Cert = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The TLS certificate, as a base64-encoded string. + + Note that the contents of this option will be added to the Nix + store as world-readable plain text. Set + [CertPath](#opt-services.zitadel.settings.TLS.CertPath) instead + if this is undesired. + ''; + }; + }; + }; + }; + default = { }; + example = lib.literalExpression '' + { + Port = 8123; + ExternalDomain = "example.com"; + TLS = { + CertPath = "/path/to/cert.pem"; + KeyPath = "/path/to/cert.key"; + }; + Database.cockroach.Host = "db.example.com"; + }; + ''; + description = '' + Contents of the runtime configuration file. See + https://zitadel.com/docs/self-hosting/manage/configure for more + details. + ''; + }; + + extraSettingsPaths = mkOption { + type = types.listOf types.path; + default = [ ]; + description = '' + A list of paths to extra settings files. These will override the + values set in [settings](#opt-services.zitadel.settings). Useful if + you want to keep sensitive secrets out of the Nix store. + ''; + }; + + steps = mkOption { + type = settingsFormat.type; + default = { }; + example = lib.literalExpression '' + { + FirstInstance = { + InstanceName = "Example"; + Org.Human = { + UserName = "foobar"; + FirstName = "Foo"; + LastName = "Bar"; + }; + }; + } + ''; + description = '' + Contents of the database initialization config file. See + https://zitadel.com/docs/self-hosting/manage/configure for more + details. + ''; + }; + + extraStepsPaths = mkOption { + type = types.listOf types.path; + default = [ ]; + description = '' + A list of paths to extra steps files. These will override the values + set in [steps](#opt-services.zitadel.steps). Useful if you want to + keep sensitive secrets out of the Nix store. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [{ + assertion = cfg.tlsMode == "enabled" + -> ((cfg.settings.TLS.Key != null || cfg.settings.TLS.KeyPath != null) + && (cfg.settings.TLS.Cert != null || cfg.settings.TLS.CertPath + != null)); + message = '' + A TLS certificate and key must be configured in + services.zitadel.settings.TLS if services.zitadel.tlsMode is enabled. + ''; + }]; + + networking.firewall.allowedTCPPorts = + lib.mkIf cfg.openFirewall [ cfg.settings.Port ]; + + systemd.services.zitadel = + let + configFile = settingsFormat.generate "config.yaml" cfg.settings; + stepsFile = settingsFormat.generate "steps.yaml" cfg.steps; + + args = lib.cli.toGNUCommandLineShell { } { + config = cfg.extraSettingsPaths ++ [ configFile ]; + steps = cfg.extraStepsPaths ++ [ stepsFile ]; + masterkeyFile = cfg.masterKeyFile; + inherit (cfg) tlsMode; + }; + in + { + description = "ZITADEL identity access management"; + path = [ cfg.package ]; + wantedBy = [ "multi-user.target" ]; + + script = '' + zitadel start-from-init ${args} + ''; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + Restart = "on-failure"; + }; + }; + + users.users.zitadel = lib.mkIf (cfg.user == "zitadel") { + isSystemUser = true; + group = cfg.group; + }; + users.groups.zitadel = lib.mkIf (cfg.group == "zitadel") { }; + }; + + meta.maintainers = with lib.maintainers; [ Sorixelle ]; +} diff --git a/pkgs/by-name/zi/zitadel/console.nix b/pkgs/by-name/zi/zitadel/console.nix new file mode 100644 index 00000000000..f2e1f26f3b8 --- /dev/null +++ b/pkgs/by-name/zi/zitadel/console.nix @@ -0,0 +1,51 @@ +{ generateProtobufCode +, version +, zitadelRepo +}: + +{ mkYarnPackage +, fetchYarnDeps +, lib +}: + +let + protobufGenerated = generateProtobufCode { + pname = "zitadel-console"; + workDir = "console"; + bufArgs = "../proto --include-imports --include-wkt"; + outputPath = "src/app/proto"; + hash = "sha256-s0dzmcjKd8ot7t+KlRlNVA9oiIDKVMnGOT/HjdaUjGI="; + }; +in +mkYarnPackage rec { + name = "zitadel-console"; + inherit version; + + src = "${zitadelRepo}/console"; + + packageJSON = ./package.json; + offlineCache = fetchYarnDeps { + yarnLock = "${src}/yarn.lock"; + hash = "sha256-48IC4LxqbkH+95k7rCmhRWT+qAlJ9CDXWwRjbric9no="; + }; + + postPatch = '' + substituteInPlace src/styles.scss \ + --replace "/node_modules/flag-icons" "flag-icons" + + substituteInPlace angular.json \ + --replace "./node_modules/tinycolor2" "../../node_modules/tinycolor2" + ''; + + buildPhase = '' + mkdir deps/console/src/app/proto + cp -r ${protobufGenerated}/* deps/console/src/app/proto/ + yarn --offline build + ''; + + installPhase = '' + cp -r deps/console/dist/console $out + ''; + + doDist = false; +} diff --git a/pkgs/by-name/zi/zitadel/package.json b/pkgs/by-name/zi/zitadel/package.json new file mode 100644 index 00000000000..0add6d2556b --- /dev/null +++ b/pkgs/by-name/zi/zitadel/package.json @@ -0,0 +1,88 @@ +{ + "name": "console", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "node prebuild.development.js && ng serve", + "build": "ng build --configuration production --base-href=/ui/console/", + "prelint": "npm run generate", + "lint": "ng lint && prettier --check src", + "lint:fix": "prettier --write src", + "generate": "buf generate ../proto --include-imports --include-wkt" + }, + "private": true, + "dependencies": { + "@angular/animations": "^16.2.0", + "@angular/cdk": "^16.2.0", + "@angular/common": "^16.2.0", + "@angular/compiler": "^16.2.0", + "@angular/core": "^16.2.0", + "@angular/forms": "^16.2.0", + "@angular/material": "^16.2.0", + "@angular/material-moment-adapter": "^16.2.0", + "@angular/platform-browser": "^16.2.0", + "@angular/platform-browser-dynamic": "^16.2.0", + "@angular/router": "^16.2.0", + "@angular/service-worker": "^16.2.0", + "@ctrl/ngx-codemirror": "^6.1.0", + "@grpc/grpc-js": "^1.8.14", + "@ngx-translate/core": "^14.0.0", + "angular-oauth2-oidc": "^15.0.1", + "angularx-qrcode": "^16.0.0", + "buffer": "^6.0.3", + "codemirror": "^5.65.8", + "cors": "^2.8.5", + "file-saver": "^2.0.5", + "flag-icons": "^6.7.0", + "google-proto-files": "^3.0.3", + "google-protobuf": "^3.21.2", + "grpc-web": "^1.4.1", + "i18n-iso-countries": "^7.6.0", + "libphonenumber-js": "^1.10.30", + "material-design-icons-iconfont": "^6.1.1", + "moment": "^2.29.4", + "opentype.js": "^1.3.4", + "ngx-color": "^9.0.0", + "rxjs": "~7.8.0", + "tinycolor2": "^1.6.0", + "tslib": "^2.4.1", + "uuid": "^9.0.0", + "zone.js": "~0.13.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^16.2.0", + "@angular-eslint/builder": "16.1.0", + "@angular-eslint/eslint-plugin": "16.1.0", + "@angular-eslint/eslint-plugin-template": "16.1.0", + "@angular-eslint/schematics": "16.1.0", + "@angular-eslint/template-parser": "16.1.0", + "@angular/cli": "^16.2.0", + "@angular/compiler-cli": "^16.2.0", + "@angular/language-service": "^16.2.0", + "@bufbuild/buf": "^1.23.1", + "@types/file-saver": "^2.0.2", + "@types/google-protobuf": "^3.15.3", + "@types/jasmine": "~4.3.3", + "@types/jasminewd2": "~2.0.10", + "@types/jsonwebtoken": "^9.0.1", + "@types/node": "^18.15.11", + "@types/opentype.js": "^1.3.4", + "@types/qrcode": "^1.5.0", + "@types/uuid": "^9.0.2", + "@typescript-eslint/eslint-plugin": "^5.59.11", + "@typescript-eslint/parser": "^5.60.1", + "codelyzer": "^6.0.2", + "eslint": "^8.44.0", + "jasmine-core": "~4.6.0", + "jasmine-spec-reporter": "~7.0.0", + "karma": "^6.4.2", + "karma-chrome-launcher": "^3.2.0", + "karma-coverage-istanbul-reporter": "^3.0.3", + "karma-jasmine": "^5.1.0", + "karma-jasmine-html-reporter": "^2.1.0", + "prettier": "^2.8.7", + "prettier-plugin-organize-imports": "^3.2.2", + "protractor": "~7.0.0", + "typescript": "^4.9.5" + } +} diff --git a/pkgs/by-name/zi/zitadel/package.nix b/pkgs/by-name/zi/zitadel/package.nix new file mode 100644 index 00000000000..cd4780965e1 --- /dev/null +++ b/pkgs/by-name/zi/zitadel/package.nix @@ -0,0 +1,150 @@ +{ stdenv +, buildGo121Module +, callPackage +, fetchFromGitHub +, lib + +, buf +, cacert +, grpc-gateway +, protoc-gen-go +, protoc-gen-go-grpc +, protoc-gen-validate +, sass +, statik +}: + +let + version = "2.37.2"; + zitadelRepo = fetchFromGitHub { + owner = "zitadel"; + repo = "zitadel"; + rev = "v${version}"; + hash = "sha256-iWEL7R7eNDV4c1CZhmxxiHHI9ExwU6gnmHI6ildaXWY="; + }; + goModulesHash = "sha256-lk4jEiI85EKk0G4JCHvCazqBBTfiNJqSfzvrJgDZ1Nc="; + + buildZitadelProtocGen = name: + buildGo121Module { + pname = "protoc-gen-${name}"; + inherit version; + + src = zitadelRepo; + + proxyVendor = true; + vendorHash = goModulesHash; + + buildPhase = '' + go install internal/protoc/protoc-gen-${name}/main.go + ''; + + postInstall = '' + mv $out/bin/main $out/bin/protoc-gen-${name} + ''; + }; + + protoc-gen-authoption = buildZitadelProtocGen "authoption"; + protoc-gen-zitadel = buildZitadelProtocGen "zitadel"; + + # Buf downloads dependencies from an external repo - there doesn't seem to + # really be any good way around it. We'll use a fixed-output derivation so it + # can download what it needs, and output the relevant generated code for use + # during the main build. + generateProtobufCode = + { pname + , nativeBuildInputs ? [ ] + , bufArgs ? "" + , workDir ? "." + , outputPath + , hash + }: + stdenv.mkDerivation { + name = "${pname}-buf-generated"; + + src = zitadelRepo; + + nativeBuildInputs = nativeBuildInputs ++ [ buf ]; + + buildPhase = '' + cd ${workDir} + export SSL_CERT_FILE="${cacert}/etc/ssl/certs/ca-bundle.crt" + HOME=$TMPDIR buf generate ${bufArgs} + ''; + + installPhase = '' + cp -r ${outputPath} $out + ''; + + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + outputHash = hash; + }; + + protobufGenerated = generateProtobufCode { + pname = "zitadel"; + nativeBuildInputs = [ + grpc-gateway + protoc-gen-authoption + protoc-gen-go + protoc-gen-go-grpc + protoc-gen-validate + protoc-gen-zitadel + ]; + outputPath = ".artifacts"; + hash = "sha256-+9UFBWBuSYNbfimKwJUSoiUh+8bDHGnPdx1MKDul1U4="; + }; +in +buildGo121Module rec { + name = "zitadel"; + inherit version; + + src = zitadelRepo; + + nativeBuildInputs = [ sass statik ]; + + proxyVendor = true; + vendorHash = goModulesHash; + + # Adapted from Makefile in repo, with dependency fetching and protobuf codegen + # bits removed + buildPhase = '' + mkdir -p pkg/grpc + cp -r ${protobufGenerated}/grpc/github.com/zitadel/zitadel/pkg/grpc/* pkg/grpc + mkdir -p openapi/v2/zitadel + cp -r ${protobufGenerated}/grpc/zitadel/ openapi/v2/zitadel + + go generate internal/api/ui/login/static/resources/generate.go + go generate internal/api/ui/login/statik/generate.go + go generate internal/notification/statik/generate.go + go generate internal/statik/generate.go + + mkdir -p docs/apis/assets + go run internal/api/assets/generator/asset_generator.go -directory=internal/api/assets/generator/ -assets=docs/apis/assets/assets.md + + cp -r ${passthru.console}/* internal/api/ui/console/static + CGO_ENABLED=0 go build -o zitadel -v -ldflags="-s -w -X 'github.com/zitadel/zitadel/cmd/build.version=${version}'" + ''; + + installPhase = '' + mkdir -p $out/bin + install -Dm755 zitadel $out/bin/ + ''; + + passthru = { + console = callPackage + (import ./console.nix { + inherit generateProtobufCode version zitadelRepo; + }) + { }; + }; + + meta = with lib; { + description = "Identity and access management platform"; + homepage = "https://zitadel.com/"; + downloadPage = "https://github.com/zitadel/zitadel/releases"; + platforms = platforms.linux ++ platforms.darwin; + license = licenses.asl20; + sourceProvenance = [ sourceTypes.fromSource ]; + maintainers = with maintainers; [ Sorixelle ]; + }; +} -- cgit 1.4.1 From 905349064876dcd7a762bd60d586591dc67556b5 Mon Sep 17 00:00:00 2001 From: Vladimír Zahradník Date: Tue, 18 Jul 2023 23:27:34 +0200 Subject: nixos/netclient: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 ++ nixos/modules/module-list.nix | 1 + nixos/modules/services/networking/netclient.nix | 27 +++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 nixos/modules/services/networking/netclient.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 3a1ccfd6bc9..4fb038f476b 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -91,6 +91,8 @@ - [ZITADEL](https://zitadel.com), a turnkey identity and access management platform. Available as [services.zitadel](#opt-services.zitadel.enable). +- [netclient](https://github.com/gravitl/netclient), an automated WireGuard® Management Client. Available as [services.netclient](#opt-services.netclient.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - `network-online.target` has been fixed to no longer time out for systems with `networking.useDHCP = true` and `networking.useNetworkd = true`. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 811b82f28ce..e94c5d906a6 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -985,6 +985,7 @@ ./services/networking/ndppd.nix ./services/networking/nebula.nix ./services/networking/netbird.nix + ./services/networking/netclient.nix ./services/networking/networkd-dispatcher.nix ./services/networking/networkmanager.nix ./services/networking/nextdns.nix diff --git a/nixos/modules/services/networking/netclient.nix b/nixos/modules/services/networking/netclient.nix new file mode 100644 index 00000000000..124735fd716 --- /dev/null +++ b/nixos/modules/services/networking/netclient.nix @@ -0,0 +1,27 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.services.netclient; +in +{ + meta.maintainers = with lib.maintainers; [ wexder ]; + + options.services.netclient = { + enable = lib.mkEnableOption (lib.mdDoc "Netclient Daemon"); + package = lib.mkPackageOptionMD pkgs "netclient" { }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + systemd.services.netclient = { + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + description = "Netclient Daemon"; + serviceConfig = { + Type = "simple"; + ExecStart = "${lib.getExe cfg.package} daemon"; + Restart = "on-failure"; + RestartSec = "15s"; + }; + }; + }; +} -- cgit 1.4.1 From 46d295f15cd526ac7d707d759923523fbe98bef9 Mon Sep 17 00:00:00 2001 From: Mikael Fangel <34864484+MikaelFangel@users.noreply.github.com> Date: Thu, 12 Oct 2023 03:29:12 +0200 Subject: nixos/gnu: remove --- nixos/modules/config/gnu.nix | 43 ------------------------------------------- nixos/modules/module-list.nix | 1 - 2 files changed, 44 deletions(-) delete mode 100644 nixos/modules/config/gnu.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/config/gnu.nix b/nixos/modules/config/gnu.nix deleted file mode 100644 index a47d299b226..00000000000 --- a/nixos/modules/config/gnu.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - options = { - gnu = lib.mkOption { - type = lib.types.bool; - default = false; - description = lib.mdDoc '' - When enabled, GNU software is chosen by default whenever a there is - a choice between GNU and non-GNU software (e.g., GNU lsh - vs. OpenSSH). - ''; - }; - }; - - config = lib.mkIf config.gnu { - - environment.systemPackages = with pkgs; - # TODO: Adjust `requiredPackages' from `system-path.nix'. - # TODO: Add Inetutils once it has the new `ifconfig'. - [ parted - #fdisk # XXX: GNU fdisk currently fails to build and it's redundant - # with the `parted' command. - nano zile - texinfo # for the stand-alone Info reader - ] - ++ lib.optional (!stdenv.isAarch32) grub2; - - - # GNU GRUB, where available. - boot.loader.grub.enable = !pkgs.stdenv.isAarch32; - - # GNU lsh. - services.openssh.enable = false; - services.lshd.enable = true; - programs.ssh.startAgent = false; - services.xserver.startGnuPGAgent = true; - - # TODO: GNU dico. - # TODO: GNU Inetutils' inetd. - # TODO: GNU Pies. - }; -} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3e814300f19..b51e2786797 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -6,7 +6,6 @@ ./config/fonts/fontdir.nix ./config/fonts/ghostscript.nix ./config/fonts/packages.nix - ./config/gnu.nix ./config/gtk/gtk-icon-cache.nix ./config/i18n.nix ./config/iproute2.nix -- cgit 1.4.1 From 04b6bd2def3b3062a09cdc617bebdc4ff923efb1 Mon Sep 17 00:00:00 2001 From: Robert Schütz Date: Sat, 14 Oct 2023 18:48:31 -0700 Subject: nixos/iptsd: init --- nixos/modules/module-list.nix | 1 + nixos/modules/services/hardware/iptsd.nix | 53 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 nixos/modules/services/hardware/iptsd.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b51e2786797..e6459e90797 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -516,6 +516,7 @@ ./services/hardware/hddfancontrol.nix ./services/hardware/illum.nix ./services/hardware/interception-tools.nix + ./services/hardware/iptsd.nix ./services/hardware/irqbalance.nix ./services/hardware/joycond.nix ./services/hardware/kanata.nix diff --git a/nixos/modules/services/hardware/iptsd.nix b/nixos/modules/services/hardware/iptsd.nix new file mode 100644 index 00000000000..8af0a6d6bbe --- /dev/null +++ b/nixos/modules/services/hardware/iptsd.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.iptsd; + format = pkgs.formats.ini { }; + configFile = format.generate "iptsd.conf" cfg.config; +in { + options.services.iptsd = { + enable = lib.mkEnableOption (lib.mdDoc "the userspace daemon for Intel Precise Touch & Stylus"); + + config = lib.mkOption { + default = { }; + description = lib.mdDoc '' + Configuration for IPTSD. See the + [reference configuration](https://github.com/linux-surface/iptsd/blob/master/etc/iptsd.conf) + for available options and defaults. + ''; + type = lib.types.submodule { + freeformType = format.type; + options = { + Touch = { + DisableOnPalm = lib.mkOption { + default = false; + description = lib.mdDoc "Ignore all touch inputs if a palm was registered on the display."; + type = lib.types.bool; + }; + DisableOnStylus = lib.mkOption { + default = false; + description = lib.mdDoc "Ignore all touch inputs if a stylus is in proximity."; + type = lib.types.bool; + }; + }; + Stylus = { + Disable = lib.mkOption { + default = false; + description = lib.mdDoc "Disables the stylus. No stylus data will be processed."; + type = lib.types.bool; + }; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.packages = [ pkgs.iptsd ]; + environment.etc."iptsd.conf".source = configFile; + systemd.services."iptsd@".restartTriggers = [ configFile ]; + services.udev.packages = [ pkgs.iptsd ]; + }; + + meta.maintainers = with lib.maintainers; [ dotlambda ]; +} -- cgit 1.4.1 From c54ab7d6438d459b57442f6d823ae0ea1f16908b Mon Sep 17 00:00:00 2001 From: Julien Malka Date: Sun, 15 Oct 2023 10:36:04 +0200 Subject: nixos/ferretdb: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/databases/ferretdb.nix | 79 +++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 nixos/modules/services/databases/ferretdb.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 69722b9ab53..34ea5cdbd65 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -91,6 +91,8 @@ - [Honk](https://humungus.tedunangst.com/r/honk), a complete ActivityPub server with minimal setup and support costs. Available as [services.honk](#opt-services.honk.enable). +- [ferretdb](https://www.ferretdb.io/), an open-source proxy, converting the MongoDB 6.0+ wire protocol queries to PostgreSQL or SQLite. Available as [services.ferretdb](options.html#opt-services.ferretdb.enable). + - [NNCP](http://www.nncpgo.org/). Added nncp-daemon and nncp-caller services. Configuration is set with [programs.nncp.settings](#opt-programs.nncp.settings) and the daemons are enabled at [services.nncp](#opt-services.nncp.caller.enable). - [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b51e2786797..aae7069fa5f 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -415,6 +415,7 @@ ./services/databases/couchdb.nix ./services/databases/dgraph.nix ./services/databases/dragonflydb.nix + ./services/databases/ferretdb.nix ./services/databases/firebird.nix ./services/databases/foundationdb.nix ./services/databases/hbase-standalone.nix diff --git a/nixos/modules/services/databases/ferretdb.nix b/nixos/modules/services/databases/ferretdb.nix new file mode 100644 index 00000000000..5b2cc59d8c0 --- /dev/null +++ b/nixos/modules/services/databases/ferretdb.nix @@ -0,0 +1,79 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.ferretdb; +in +{ + + meta.maintainers = with lib.maintainers; [ julienmalka camillemndn ]; + + options = { + services.ferretdb = { + enable = mkEnableOption "FerretDB, an Open Source MongoDB alternative."; + + package = mkOption { + type = types.package; + example = literalExpression "pkgs.ferretdb"; + default = pkgs.ferretdb; + defaultText = "pkgs.ferretdb"; + description = "FerretDB package to use."; + }; + + settings = lib.mkOption { + type = + lib.types.submodule { freeformType = with lib.types; attrsOf str; }; + example = { + FERRETDB_LOG_LEVEL = "warn"; + FERRETDB_MODE = "normal"; + }; + description = '' + Additional configuration for FerretDB, see + + for supported values. + ''; + }; + }; + }; + + config = mkIf cfg.enable + { + + services.ferretdb.settings = { + FERRETDB_HANDLER = lib.mkDefault "sqlite"; + FERRETDB_SQLITE_URL = lib.mkDefault "file:/var/lib/ferretdb/"; + }; + + systemd.services.ferretdb = { + description = "FerretDB"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = cfg.settings; + serviceConfig = { + Type = "simple"; + StateDirectory = "ferretdb"; + WorkingDirectory = "/var/lib/ferretdb"; + ExecStart = "${cfg.package}/bin/ferretdb"; + Restart = "on-failure"; + ProtectHome = true; + ProtectSystem = "strict"; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + NoNewPrivileges = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + DynamicUser = true; + }; + }; + }; +} + -- cgit 1.4.1 From fb3723fe52894c49bd4b2fb92244a289d4124b1f Mon Sep 17 00:00:00 2001 From: Jean-François Roche Date: Mon, 16 Oct 2023 13:10:15 +0200 Subject: nixos/tang: create module for tang server (#247037) This commit adds a module for the tang server and the related nixos test. --- nixos/modules/module-list.nix | 1 + nixos/modules/services/security/tang.nix | 95 ++++++++++++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/tang.nix | 81 +++++++++++++++++++++++++++ pkgs/servers/tang/default.nix | 13 +++-- 5 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 nixos/modules/services/security/tang.nix create mode 100644 nixos/tests/tang.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index aae7069fa5f..3e5e4e4cc8c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1164,6 +1164,7 @@ ./services/security/sshguard.nix ./services/security/sslmate-agent.nix ./services/security/step-ca.nix + ./services/security/tang.nix ./services/security/tor.nix ./services/security/torify.nix ./services/security/torsocks.nix diff --git a/nixos/modules/services/security/tang.nix b/nixos/modules/services/security/tang.nix new file mode 100644 index 00000000000..9cb0a22fca4 --- /dev/null +++ b/nixos/modules/services/security/tang.nix @@ -0,0 +1,95 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.tang; +in +{ + options.services.tang = { + enable = mkEnableOption "tang"; + + package = mkOption { + type = types.package; + default = pkgs.tang; + defaultText = literalExpression "pkgs.tang"; + description = mdDoc "The tang package to use."; + }; + + listenStream = mkOption { + type = with types; listOf str; + default = [ "7654" ]; + example = [ "198.168.100.1:7654" "[2001:db8::1]:7654" "7654" ]; + description = mdDoc '' + Addresses and/or ports on which tang should listen. + For detailed syntax see ListenStream in {manpage}`systemd.socket(5)`. + ''; + }; + + ipAddressAllow = mkOption { + example = [ "192.168.1.0/24" ]; + type = types.listOf types.str; + description = '' + Whitelist a list of address prefixes. + Preferably, internal addresses should be used. + ''; + }; + + }; + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.services."tangd@" = { + description = "Tang server"; + path = [ cfg.package ]; + serviceConfig = { + StandardInput = "socket"; + StandardOutput = "socket"; + StandardError = "journal"; + DynamicUser = true; + StateDirectory = "tang"; + RuntimeDirectory = "tang"; + StateDirectoryMode = "700"; + UMask = "0077"; + CapabilityBoundingSet = [ "" ]; + ExecStart = "${cfg.package}/libexec/tangd %S/tang"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + DeviceAllow = [ "/dev/stdin" ]; + RestrictAddressFamilies = [ "AF_UNIX" ]; + DevicePolicy = "strict"; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; + IPAddressDeny = "any"; + IPAddressAllow = cfg.ipAddressAllow; + }; + }; + + systemd.sockets.tangd = { + description = "Tang server"; + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenStream = cfg.listenStream; + Accept = "yes"; + IPAddressDeny = "any"; + IPAddressAllow = cfg.ipAddressAllow; + }; + }; + }; + meta.maintainers = with lib.maintainers; [ jfroche julienmalka ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index dac3e1d6973..1ac65df44fd 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -807,6 +807,7 @@ in { systemd-userdbd = handleTest ./systemd-userdbd.nix {}; systemd-homed = handleTest ./systemd-homed.nix {}; tandoor-recipes = handleTest ./tandoor-recipes.nix {}; + tang = handleTest ./tang.nix {}; taskserver = handleTest ./taskserver.nix {}; tayga = handleTest ./tayga.nix {}; teeworlds = handleTest ./teeworlds.nix {}; diff --git a/nixos/tests/tang.nix b/nixos/tests/tang.nix new file mode 100644 index 00000000000..10486a9feb8 --- /dev/null +++ b/nixos/tests/tang.nix @@ -0,0 +1,81 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "tang"; + meta = with pkgs.lib.maintainers; { + maintainers = [ jfroche ]; + }; + + nodes.server = + { config + , pkgs + , modulesPath + , ... + }: { + imports = [ + "${modulesPath}/../tests/common/auto-format-root-device.nix" + ]; + virtualisation = { + emptyDiskImages = [ 512 ]; + useBootLoader = true; + useEFIBoot = true; + # This requires to have access + # to a host Nix store as + # the new root device is /dev/vdb + # an empty 512MiB drive, containing no Nix store. + mountHostNixStore = true; + }; + + boot.loader.systemd-boot.enable = true; + + networking.interfaces.eth1.ipv4.addresses = [ + { address = "192.168.0.1"; prefixLength = 24; } + ]; + + environment.systemPackages = with pkgs; [ clevis tang cryptsetup ]; + services.tang = { + enable = true; + ipAddressAllow = [ "127.0.0.1/32" ]; + }; + }; + testScript = '' + start_all() + machine.wait_for_unit("sockets.target") + + with subtest("Check keys are generated"): + machine.wait_until_succeeds("curl -v http://127.0.0.1:7654/adv") + key = machine.wait_until_succeeds("tang-show-keys 7654") + + with subtest("Check systemd access list"): + machine.succeed("ping -c 3 192.168.0.1") + machine.fail("curl -v --connect-timeout 3 http://192.168.0.1:7654/adv") + + with subtest("Check basic encrypt and decrypt message"): + machine.wait_until_succeeds(f"""echo 'Hello World' | clevis encrypt tang '{{ "url": "http://127.0.0.1:7654", "thp":"{key}"}}' > /tmp/encrypted""") + decrypted = machine.wait_until_succeeds("clevis decrypt < /tmp/encrypted") + assert decrypted.strip() == "Hello World" + machine.wait_until_succeeds("tang-show-keys 7654") + + with subtest("Check encrypt and decrypt disk"): + machine.succeed("cryptsetup luksFormat --force-password --batch-mode /dev/vdb <<<'password'") + machine.succeed(f"""clevis luks bind -s1 -y -f -d /dev/vdb tang '{{ "url": "http://127.0.0.1:7654", "thp":"{key}" }}' <<< 'password' """) + clevis_luks = machine.succeed("clevis luks list -d /dev/vdb") + assert clevis_luks.strip() == """1: tang '{"url":"http://127.0.0.1:7654"}'""" + machine.succeed("clevis luks unlock -d /dev/vdb") + machine.succeed("find /dev/mapper -name 'luks*' -exec cryptsetup close {} +") + machine.succeed("clevis luks unlock -d /dev/vdb") + machine.succeed("find /dev/mapper -name 'luks*' -exec cryptsetup close {} +") + # without tang available, unlock should fail + machine.succeed("systemctl stop tangd.socket") + machine.fail("clevis luks unlock -d /dev/vdb") + machine.succeed("systemctl start tangd.socket") + + with subtest("Rotate server keys"): + machine.succeed("${pkgs.tang}/libexec/tangd-rotate-keys -d /var/lib/tang") + machine.succeed("clevis luks unlock -d /dev/vdb") + machine.succeed("find /dev/mapper -name 'luks*' -exec cryptsetup close {} +") + + with subtest("Test systemd service security"): + output = machine.succeed("systemd-analyze security tangd@.service") + machine.log(output) + assert output[-9:-1] == "SAFE :-}" + ''; +}) diff --git a/pkgs/servers/tang/default.nix b/pkgs/servers/tang/default.nix index 227daa2cfb9..4206973dbd1 100644 --- a/pkgs/servers/tang/default.nix +++ b/pkgs/servers/tang/default.nix @@ -13,6 +13,7 @@ , testers , tang , gitUpdater +, nixosTests }: stdenv.mkDerivation rec { @@ -53,10 +54,13 @@ stdenv.mkDerivation rec { ''; passthru = { - tests.version = testers.testVersion { - package = tang; - command = "${tang}/libexec/tangd --version"; - version = "tangd ${version}"; + tests = { + inherit (nixosTests) tang; + version = testers.testVersion { + package = tang; + command = "${tang}/libexec/tangd --version"; + version = "tangd ${version}"; + }; }; updateScript = gitUpdater { }; }; @@ -67,5 +71,6 @@ stdenv.mkDerivation rec { changelog = "https://github.com/latchset/tang/releases/tag/v${version}"; maintainers = with lib.maintainers; [ fpletz ]; license = lib.licenses.gpl3Plus; + mainProgram = "tangd"; }; } -- cgit 1.4.1 From e94820dfb2e131db750343662ffe93067bc8f158 Mon Sep 17 00:00:00 2001 From: Jennifer Graul Date: Fri, 7 Jul 2023 13:46:40 +0200 Subject: nixos/librenms: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/monitoring/librenms.nix | 624 ++++++++++++++++++++++ 3 files changed, 627 insertions(+) create mode 100644 nixos/modules/services/monitoring/librenms.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index db3fd62d36f..4cc5fc29ed6 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -66,6 +66,8 @@ - [Prometheus MySQL exporter](https://github.com/prometheus/mysqld_exporter), a MySQL server exporter for Prometheus. Available as [services.prometheus.exporters.mysqld](#opt-services.prometheus.exporters.mysqld.enable). +- [LibreNMS](https://www.librenms.org), a auto-discovering PHP/MySQL/SNMP based network monitoring. Available as [services.librenms](#opt-services.librenms.enable). + - [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable). - [stalwart-mail](https://stalw.art), an all-in-one email server (SMTP, IMAP, JMAP). Available as [services.stalwart-mail](#opt-services.stalwart-mail.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3e5e4e4cc8c..9b347527ab0 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -775,6 +775,7 @@ ./services/monitoring/kapacitor.nix ./services/monitoring/karma.nix ./services/monitoring/kthxbye.nix + ./services/monitoring/librenms.nix ./services/monitoring/loki.nix ./services/monitoring/longview.nix ./services/monitoring/mackerel-agent.nix diff --git a/nixos/modules/services/monitoring/librenms.nix b/nixos/modules/services/monitoring/librenms.nix new file mode 100644 index 00000000000..08a46754e0e --- /dev/null +++ b/nixos/modules/services/monitoring/librenms.nix @@ -0,0 +1,624 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.librenms; + settingsFormat = pkgs.formats.json {}; + configJson = settingsFormat.generate "librenms-config.json" cfg.settings; + + package = pkgs.librenms.override { + logDir = cfg.logDir; + dataDir = cfg.dataDir; + }; + + phpOptions = '' + log_errors = on + post_max_size = 100M + upload_max_filesize = 100M + date.timezone = "${config.time.timeZone}" + ''; + phpIni = pkgs.runCommand "php.ini" { + inherit (package) phpPackage; + inherit phpOptions; + preferLocalBuild = true; + passAsFile = [ "phpOptions" ]; + } '' + cat $phpPackage/etc/php.ini $phpOptionsPath > $out + ''; + + artisanWrapper = pkgs.writeShellScriptBin "librenms-artisan" '' + cd ${package} + sudo=exec + if [[ "$USER" != ${cfg.user} ]]; then + sudo='exec /run/wrappers/bin/sudo -u ${cfg.user}' + fi + $sudo ${package}/artisan $* + ''; + + lnmsWrapper = pkgs.writeShellScriptBin "lnms" '' + cd ${package} + exec ${package}/lnms $* + ''; + + configFile = pkgs.writeText "config.php" '' + cfg.database.host == "localhost"; + message = "The database host must be \"localhost\" if services.librenms.database.createLocally is set to true."; + } + { + assertion = !(cfg.useDistributedPollers && cfg.distributedPoller.enable); + message = "The LibreNMS instance can't be a distributed poller and a full instance at the same time."; + } + ]; + + users.users.${cfg.user} = { + group = "${cfg.group}"; + isSystemUser = true; + }; + + users.groups.${cfg.group} = { }; + + services.librenms.settings = { + # basic configs + "user" = cfg.user; + "own_hostname" = cfg.hostname; + "base_url" = lib.mkDefault "/"; + "auth_mechanism" = lib.mkDefault "mysql"; + + # disable auto update function (won't work with NixOS) + "update" = false; + + # enable fast ping by default + "ping_rrd_step" = 60; + + # one minute polling + "rrd.step" = if cfg.enableOneMinutePolling then 60 else 300; + "rrd.heartbeat" = if cfg.enableOneMinutePolling then 120 else 600; + } // (lib.optionalAttrs cfg.distributedPoller.enable { + "distributed_poller" = true; + "distributed_poller_name" = lib.mkIf (cfg.distributedPoller.name != null) cfg.distributedPoller.name; + "distributed_poller_group" = cfg.distributedPoller.group; + "distributed_billing" = cfg.distributedPoller.distributedBilling; + "distributed_poller_memcached_host" = cfg.distributedPoller.memcachedHost; + "distributed_poller_memcached_port" = cfg.distributedPoller.memcachedPort; + "rrdcached" = "${cfg.distributedPoller.rrdcachedHost}:${toString cfg.distributedPoller.rrdcachedPort}"; + }) // (lib.optionalAttrs cfg.useDistributedPollers { + "distributed_poller" = true; + # still enable a local poller with distributed polling + "distributed_poller_group" = lib.mkDefault "0"; + "distributed_billing" = lib.mkDefault true; + "distributed_poller_memcached_host" = "localhost"; + "distributed_poller_memcached_port" = 11211; + "rrdcached" = "localhost:42217"; + }); + + services.memcached = lib.mkIf cfg.useDistributedPollers { + enable = true; + listen = "0.0.0.0"; + }; + + systemd.services.rrdcached = lib.mkIf cfg.useDistributedPollers { + description = "rrdcached"; + after = [ "librenms-setup.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "forking"; + User = cfg.user; + Group = cfg.group; + LimitNOFILE = 16384; + RuntimeDirectory = "rrdcached"; + PidFile = "/run/rrdcached/rrdcached.pid"; + # rrdcached params from https://docs.librenms.org/Extensions/Distributed-Poller/#config-sample + ExecStart = "${pkgs.rrdtool}/bin/rrdcached -l 0:42217 -R -j ${cfg.dataDir}/rrdcached-journal/ -F -b ${cfg.dataDir}/rrd -B -w 1800 -z 900 -p /run/rrdcached/rrdcached.pid"; + }; + }; + + services.mysql = lib.mkIf cfg.database.createLocally { + enable = true; + package = lib.mkDefault pkgs.mariadb; + settings.mysqld = { + innodb_file_per_table = 1; + lower_case_table_names = 0; + } // (lib.optionalAttrs cfg.useDistributedPollers { + bind-address = "0.0.0.0"; + }); + ensureDatabases = [ cfg.database.database ]; + ensureUsers = [ + { + name = cfg.database.username; + ensurePermissions = { + "${cfg.database.database}.*" = "ALL PRIVILEGES"; + }; + } + ]; + initialScript = lib.mkIf cfg.useDistributedPollers (pkgs.writeText "mysql-librenms-init" '' + CREATE USER IF NOT EXISTS '${cfg.database.username}'@'%'; + GRANT ALL PRIVILEGES ON ${cfg.database.database}.* TO '${cfg.database.username}'@'%'; + ''); + }; + + services.nginx = lib.mkIf (!cfg.distributedPoller.enable) { + enable = true; + virtualHosts."${cfg.hostname}" = lib.mkMerge [ + cfg.nginx + { + root = lib.mkForce "${package}/html"; + locations."/" = { + index = "index.php"; + tryFiles = "$uri $uri/ /index.php?$query_string"; + }; + locations."~ .php$".extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools."librenms".socket}; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + ''; + } + ]; + }; + + services.phpfpm.pools.librenms = lib.mkIf (!cfg.distributedPoller.enable) { + user = cfg.user; + group = cfg.group; + inherit (package) phpPackage; + inherit phpOptions; + settings = { + "listen.mode" = "0660"; + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; + } // cfg.poolConfig; + }; + + systemd.services.librenms-scheduler = { + description = "LibreNMS Scheduler"; + path = [ pkgs.unixtools.whereis ]; + serviceConfig = { + Type = "oneshot"; + WorkingDirectory = package; + User = cfg.user; + Group = cfg.group; + ExecStart = "${artisanWrapper}/bin/librenms-artisan schedule:run"; + }; + }; + + systemd.timers.librenms-scheduler = { + description = "LibreNMS Scheduler"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "minutely"; + AccuracySec = "1second"; + }; + }; + + systemd.services.librenms-setup = { + description = "Preparation tasks for LibreNMS"; + before = [ "phpfpm-librenms.service" ]; + after = [ "systemd-tmpfiles-setup.service" ] + ++ (lib.optional (cfg.database.host == "localhost") "mysql.service"); + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ package configFile ]; + path = [ pkgs.mariadb pkgs.unixtools.whereis pkgs.gnused ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; + User = cfg.user; + Group = cfg.group; + ExecStartPre = lib.mkIf cfg.database.createLocally [ "!${pkgs.writeShellScript "librenms-db-init" '' + DB_PASSWORD=$(cat ${cfg.database.passwordFile} | tr -d '\n') + echo "ALTER USER '${cfg.database.username}'@'localhost' IDENTIFIED BY '$DB_PASSWORD';" | ${pkgs.mariadb}/bin/mysql + ${lib.optionalString cfg.useDistributedPollers '' + echo "ALTER USER '${cfg.database.username}'@'%' IDENTIFIED BY '$DB_PASSWORD';" | ${pkgs.mariadb}/bin/mysql + ''} + ''}"]; + }; + script = '' + set -euo pipefail + + # config setup + ln -sf ${configFile} ${cfg.dataDir}/config.php + ${pkgs.envsubst}/bin/envsubst -i ${configJson} -o ${cfg.dataDir}/config.json + export PHPRC=${phpIni} + + if [[ ! -s ${cfg.dataDir}/.env ]]; then + # init .env file + echo "APP_KEY=" > ${cfg.dataDir}/.env + ${artisanWrapper}/bin/librenms-artisan key:generate --ansi + ${artisanWrapper}/bin/librenms-artisan webpush:vapid + echo "" >> ${cfg.dataDir}/.env + echo -n "NODE_ID=" >> ${cfg.dataDir}/.env + ${package.phpPackage}/bin/php -r "echo uniqid();" >> ${cfg.dataDir}/.env + echo "" >> ${cfg.dataDir}/.env + else + # .env file already exists --> only update database and cache config + ${pkgs.gnused}/bin/sed -i /^DB_/d ${cfg.dataDir}/.env + ${pkgs.gnused}/bin/sed -i /^CACHE_DRIVER/d ${cfg.dataDir}/.env + fi + ${lib.optionalString (cfg.useDistributedPollers || cfg.distributedPoller.enable) '' + echo "CACHE_DRIVER=memcached" >> ${cfg.dataDir}/.env + ''} + echo "DB_HOST=${cfg.database.host}" >> ${cfg.dataDir}/.env + echo "DB_PORT=${toString cfg.database.port}" >> ${cfg.dataDir}/.env + echo "DB_DATABASE=${cfg.database.database}" >> ${cfg.dataDir}/.env + echo "DB_USERNAME=${cfg.database.username}" >> ${cfg.dataDir}/.env + echo -n "DB_PASSWORD=" >> ${cfg.dataDir}/.env + cat ${cfg.database.passwordFile} >> ${cfg.dataDir}/.env + + # clear cache after update + OLD_VERSION=$(cat ${cfg.dataDir}/version) + if [[ $OLD_VERSION != "${package.version}" ]]; then + rm -r ${cfg.dataDir}/cache/* + echo "${package.version}" > ${cfg.dataDir}/version + fi + + # convert rrd files when the oneMinutePolling option is changed + OLD_ENABLED=$(cat ${cfg.dataDir}/one_minute_enabled) + if [[ $OLD_ENABLED != "${lib.boolToString cfg.enableOneMinutePolling}" ]]; then + ${package}/scripts/rrdstep.php -h all + echo "${lib.boolToString cfg.enableOneMinutePolling}" > ${cfg.dataDir}/one_minute_enabled + fi + + # migrate db + ${artisanWrapper}/bin/librenms-artisan migrate --force --no-interaction + ''; + }; + + programs.mtr.enable = true; + + services.logrotate = { + enable = true; + settings."${cfg.logDir}/librenms.log" = { + su = "${cfg.user} ${cfg.group}"; + create = "0640 ${cfg.user} ${cfg.group}"; + rotate = 6; + frequency = "weekly"; + compress = true; + delaycompress = true; + missingok = true; + notifempty = true; + }; + }; + + services.cron = { + enable = true; + systemCronJobs = let + env = "PHPRC=${phpIni}"; + in [ + # based on crontab provided by LibreNMS + "33 */6 * * * ${cfg.user} ${env} ${package}/cronic ${package}/discovery-wrapper.py 1" + "*/5 * * * * ${cfg.user} ${env} ${package}/discovery.php -h new >> /dev/null 2>&1" + + "${if cfg.enableOneMinutePolling then "*" else "*/5"} * * * * ${cfg.user} ${env} ${package}/cronic ${package}/poller-wrapper.py ${toString cfg.pollerThreads}" + "* * * * * ${cfg.user} ${env} ${package}/alerts.php >> /dev/null 2>&1" + + "*/5 * * * * ${cfg.user} ${env} ${package}/poll-billing.php >> /dev/null 2>&1" + "01 * * * * ${cfg.user} ${env} ${package}/billing-calculate.php >> /dev/null 2>&1" + "*/5 * * * * ${cfg.user} ${env} ${package}/check-services.php >> /dev/null 2>&1" + + # extra: fast ping + "* * * * * ${cfg.user} ${env} ${package}/ping.php >> /dev/null 2>&1" + + # daily.sh tasks are split to exclude update + "19 0 * * * ${cfg.user} ${env} ${package}/daily.sh cleanup >> /dev/null 2>&1" + "19 0 * * * ${cfg.user} ${env} ${package}/daily.sh notifications >> /dev/null 2>&1" + "19 0 * * * ${cfg.user} ${env} ${package}/daily.sh peeringdb >> /dev/null 2>&1" + "19 0 * * * ${cfg.user} ${env} ${package}/daily.sh mac_oui >> /dev/null 2>&1" + ]; + }; + + security.wrappers = { + fping = { + setuid = true; + owner = "root"; + group = "root"; + source = "${pkgs.fping}/bin/fping"; + }; + }; + + environment.systemPackages = [ artisanWrapper lnmsWrapper ]; + + systemd.tmpfiles.rules = [ + "d ${cfg.logDir} 0750 ${cfg.user} ${cfg.group} - -" + "f ${cfg.logDir}/librenms.log 0640 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -" + "f ${cfg.dataDir}/.env 0600 ${cfg.user} ${cfg.group} - -" + "f ${cfg.dataDir}/version 0600 ${cfg.user} ${cfg.group} - -" + "f ${cfg.dataDir}/one_minute_enabled 0600 ${cfg.user} ${cfg.group} - -" + "f ${cfg.dataDir}/config.json 0600 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/app 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/debugbar 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/framework 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/framework/cache 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/framework/sessions 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/framework/views 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/storage/logs 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/rrd 0700 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/cache 0700 ${cfg.user} ${cfg.group} - -" + ] ++ lib.optionals cfg.useDistributedPollers [ + "d ${cfg.dataDir}/rrdcached-journal 0700 ${cfg.user} ${cfg.group} - -" + ]; + + }; + + meta.maintainers = lib.teams.wdz.members; +} -- cgit 1.4.1 From 4164383dd4f63c5725f099e618665fe0130b49ef Mon Sep 17 00:00:00 2001 From: Bjørn Forsman Date: Sun, 17 Sep 2023 20:03:50 +0200 Subject: nixos/deconz: init Add a NixOS module for the deCONZ Zigbee gateway service. --- nixos/modules/module-list.nix | 1 + nixos/modules/services/networking/deconz.nix | 125 +++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 nixos/modules/services/networking/deconz.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 9b347527ab0..f7549a6a0b0 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -882,6 +882,7 @@ ./services/networking/croc.nix ./services/networking/dae.nix ./services/networking/dante.nix + ./services/networking/deconz.nix ./services/networking/dhcpcd.nix ./services/networking/dnscache.nix ./services/networking/dnscrypt-proxy2.nix diff --git a/nixos/modules/services/networking/deconz.nix b/nixos/modules/services/networking/deconz.nix new file mode 100644 index 00000000000..1fe10373321 --- /dev/null +++ b/nixos/modules/services/networking/deconz.nix @@ -0,0 +1,125 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.deconz; + name = "deconz"; + stateDir = "/var/lib/${name}"; + # ref. upstream deconz.service + capabilities = + lib.optionals (cfg.httpPort < 1024 || cfg.wsPort < 1024) [ "CAP_NET_BIND_SERVICE" ] + ++ lib.optionals (cfg.allowRebootSystem) [ "CAP_SYS_BOOT" ] + ++ lib.optionals (cfg.allowRestartService) [ "CAP_KILL" ] + ++ lib.optionals (cfg.allowSetSystemTime) [ "CAP_SYS_TIME" ]; +in +{ + options.services.deconz = { + + enable = lib.mkEnableOption "deCONZ, a Zigbee gateway for use with ConBee hardware (https://phoscon.de/en/conbee2)"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.deconz; + defaultText = lib.literalExpression "pkgs.deconz"; + description = "Which deCONZ package to use."; + }; + + device = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + Force deCONZ to use a specific USB device (e.g. /dev/ttyACM0). By + default it does a search. + ''; + }; + + listenAddress = lib.mkOption { + type = lib.types.str; + default = "127.0.0.1"; + description = '' + Pin deCONZ to the network interface specified through the provided IP + address. This applies for the webserver as well as the websocket + notifications. + ''; + }; + + httpPort = lib.mkOption { + type = lib.types.port; + default = 80; + description = "TCP port for the web server."; + }; + + wsPort = lib.mkOption { + type = lib.types.port; + default = 443; + description = "TCP port for the WebSocket."; + }; + + openFirewall = lib.mkEnableOption "open up the service ports in the firewall"; + + allowRebootSystem = lib.mkEnableOption "allow rebooting the system"; + + allowRestartService = lib.mkEnableOption "allow killing/restarting processes"; + + allowSetSystemTime = lib.mkEnableOption "allow setting the system time"; + + extraArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ + "--dbg-info=1" + "--dbg-err=2" + ]; + description = '' + Extra command line arguments for deCONZ, see + https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/deCONZ-command-line-parameters. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ + cfg.httpPort + cfg.wsPort + ]; + + services.udev.packages = [ cfg.package ]; + + systemd.services.deconz = { + description = "deCONZ Zigbee gateway"; + wantedBy = [ "multi-user.target" ]; + preStart = '' + # The service puts a nix store path reference in here, and that path can + # be garbage collected. Ensure the file gets "refreshed" on every start. + rm -f ${stateDir}/.local/share/dresden-elektronik/deCONZ/zcldb.txt + ''; + environment = { + HOME = stateDir; + XDG_RUNTIME_DIR = "/run/${name}"; + }; + serviceConfig = { + ExecStart = + "${lib.getExe cfg.package}" + + " -platform minimal" + + " --http-listen=${cfg.listenAddress}" + + " --http-port=${toString cfg.httpPort}" + + " --ws-port=${toString cfg.wsPort}" + + " --auto-connect=1" + + (lib.optionalString (cfg.device != null) " --dev=${cfg.device}") + + " " + (lib.escapeShellArgs cfg.extraArgs); + Restart = "on-failure"; + AmbientCapabilities = capabilities; + CapabilityBoundingSet = capabilities; + UMask = "0027"; + DynamicUser = true; + RuntimeDirectory = name; + RuntimeDirectoryMode = "0700"; + StateDirectory = name; + WorkingDirectory = stateDir; + # For access to /dev/ttyACM0 (ConBee). + SupplementaryGroups = [ "dialout" ]; + ProtectHome = true; + }; + }; + }; +} -- cgit 1.4.1 From 8009330112444a049515f90c75c34c4c711fde82 Mon Sep 17 00:00:00 2001 From: nat Date: Sun, 15 Oct 2023 23:58:52 +0200 Subject: nixos/microbin: add module --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/microbin.nix | 93 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 nixos/modules/services/web-apps/microbin.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f7549a6a0b0..e170350dbbc 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1266,6 +1266,7 @@ ./services/web-apps/mattermost.nix ./services/web-apps/mediawiki.nix ./services/web-apps/meme-bingo-web.nix + ./services/web-apps/microbin.nix ./services/web-apps/miniflux.nix ./services/web-apps/monica.nix ./services/web-apps/moodle.nix diff --git a/nixos/modules/services/web-apps/microbin.nix b/nixos/modules/services/web-apps/microbin.nix new file mode 100644 index 00000000000..233bfac6e69 --- /dev/null +++ b/nixos/modules/services/web-apps/microbin.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.microbin; +in +{ + options.services.microbin = { + enable = lib.mkEnableOption (lib.mdDoc "MicroBin is a super tiny, feature rich, configurable paste bin web application"); + + package = lib.mkPackageOption pkgs "microbin" { }; + + settings = lib.mkOption { + type = lib.types.submodule { freeformType = with lib.types; attrsOf (oneOf [ bool int str ]); }; + default = { }; + example = { + MICROBIN_PORT = 8080; + MICROBIN_HIDE_LOGO = false; + }; + description = lib.mdDoc '' + Additional configuration for MicroBin, see + + for supported values. + + For secrets use passwordFile option instead. + ''; + }; + + dataDir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/microbin"; + description = lib.mdDoc "Default data folder for MicroBin."; + }; + + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/secrets/microbin.env"; + description = lib.mdDoc '' + Path to file containing environment variables. + Useful for passing down secrets. + Variables that can be considered secrets are: + - MICROBIN_BASIC_AUTH_USERNAME + - MICROBIN_BASIC_AUTH_PASSWORD + - MICROBIN_ADMIN_USERNAME + - MICROBIN_ADMIN_PASSWORD + - MICROBIN_UPLOADER_PASSWORD + ''; + }; + }; + + config = lib.mkIf cfg.enable { + services.microbin.settings = with lib; { + MICROBIN_BIND = mkDefault "0.0.0.0"; + MICROBIN_DISABLE_TELEMETRY = mkDefault true; + MICROBIN_LIST_SERVER = mkDefault false; + MICROBIN_PORT = mkDefault "8080"; + }; + + systemd.services.microbin = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = lib.mapAttrs (_: v: if lib.isBool v then lib.boolToString v else toString v) cfg.settings; + serviceConfig = { + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + DevicePolicy = "closed"; + DynamicUser = true; + EnvironmentFile = lib.optional (cfg.passwordFile != null) cfg.passwordFile; + ExecStart = "${cfg.package}/bin/microbin"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ReadWritePaths = cfg.dataDir; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + StateDirectory = "microbin"; + SystemCallArchitectures = [ "native" ]; + SystemCallFilter = [ "@system-service" ]; + WorkingDirectory = cfg.dataDir; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ surfaceflinger ]; +} -- cgit 1.4.1 From f3ad4def37a26d06a3e59988c9b2fd8d63f26f0e Mon Sep 17 00:00:00 2001 From: ckie Date: Wed, 4 Oct 2023 17:13:20 +0300 Subject: nixos/rkvm: init Co-authored-by: Lin Jian --- nixos/modules/module-list.nix | 1 + nixos/modules/services/misc/rkvm.nix | 164 +++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 nixos/modules/services/misc/rkvm.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 29fcabaefad..a56400cbabf 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -706,6 +706,7 @@ ./services/misc/ripple-data-api.nix ./services/misc/rippled.nix ./services/misc/rmfakecloud.nix + ./services/misc/rkvm.nix ./services/misc/rshim.nix ./services/misc/safeeyes.nix ./services/misc/sdrplay.nix diff --git a/nixos/modules/services/misc/rkvm.nix b/nixos/modules/services/misc/rkvm.nix new file mode 100644 index 00000000000..582e8511ed9 --- /dev/null +++ b/nixos/modules/services/misc/rkvm.nix @@ -0,0 +1,164 @@ +{ options, config, pkgs, lib, ... }: + +with lib; +let + opt = options.services.rkvm; + cfg = config.services.rkvm; + toml = pkgs.formats.toml { }; +in +{ + meta.maintainers = with maintainers; [ ckie ]; + + options.services.rkvm = { + enable = mkOption { + default = cfg.server.enable || cfg.client.enable; + defaultText = literalExpression "config.${opt.server.enable} || config.${opt.client.enable}"; + type = types.bool; + description = mdDoc '' + Whether to enable rkvm, a Virtual KVM switch for Linux machines. + ''; + }; + + package = mkPackageOption pkgs "rkvm" { }; + + server = { + enable = mkEnableOption "the rkvm server daemon (input transmitter)"; + + settings = mkOption { + type = types.submodule + { + freeformType = toml.type; + options = { + listen = mkOption { + type = types.str; + default = "0.0.0.0:5258"; + description = mdDoc '' + An internet socket address to listen on, either IPv4 or IPv6. + ''; + }; + + switch-keys = mkOption { + type = types.listOf types.str; + default = [ "left-alt" "left-ctrl" ]; + description = mdDoc '' + A key list specifying a host switch combination. + + _A list of key names is available in ._ + ''; + }; + + certificate = mkOption { + type = types.path; + default = "/etc/rkvm/certificate.pem"; + description = mdDoc '' + TLS certificate path. + + ::: {.note} + This should be generated with {command}`rkvm-certificate-gen`. + ::: + ''; + }; + + key = mkOption { + type = types.path; + default = "/etc/rkvm/key.pem"; + description = mdDoc '' + TLS key path. + + ::: {.note} + This should be generated with {command}`rkvm-certificate-gen`. + ::: + ''; + }; + + password = mkOption { + type = types.str; + description = mdDoc '' + Shared secret token to authenticate the client. + Make sure this matches your client's config. + ''; + }; + }; + }; + + default = { }; + description = mdDoc "Structured server daemon configuration"; + }; + }; + + client = { + enable = mkEnableOption "the rkvm client daemon (input receiver)"; + + settings = mkOption { + type = types.submodule + { + freeformType = toml.type; + options = { + server = mkOption { + type = types.str; + example = "192.168.0.123:5258"; + description = mdDoc '' + An RKVM server's internet socket address, either IPv4 or IPv6. + ''; + }; + + certificate = mkOption { + type = types.path; + default = "/etc/rkvm/certificate.pem"; + description = mdDoc '' + TLS ceritficate path. + + ::: {.note} + This should be generated with {command}`rkvm-certificate-gen`. + ::: + ''; + }; + + password = mkOption { + type = types.str; + description = mdDoc '' + Shared secret token to authenticate the client. + Make sure this matches your server's config. + ''; + }; + }; + }; + + default = {}; + description = mdDoc "Structured client daemon configuration"; + }; + }; + + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.services = + let + mkBase = component: { + description = "RKVM ${component}"; + wantedBy = [ "multi-user.target" ]; + after = { + server = [ "network.target" ]; + client = [ "network-online.target" ]; + }.${component}; + wants = { + server = [ ]; + client = [ "network-online.target" ]; + }.${component}; + serviceConfig = { + ExecStart = "${cfg.package}/bin/rkvm-${component} ${toml.generate "rkvm-${component}.toml" cfg.${component}.settings}"; + Restart = "always"; + RestartSec = 5; + Type = "simple"; + }; + }; + in + { + rkvm-server = mkIf cfg.server.enable (mkBase "server"); + rkvm-client = mkIf cfg.client.enable (mkBase "client"); + }; + }; + +} -- cgit 1.4.1 From ace2bcc2d284a3de2d26465f71e7b7689a66e680 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Wed, 18 Oct 2023 09:09:15 +0200 Subject: nixos/modules: add missing projecteur entry --- nixos/modules/module-list.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f7549a6a0b0..c248aa6f976 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -231,6 +231,7 @@ ./programs/pantheon-tweaks.nix ./programs/partition-manager.nix ./programs/plotinus.nix + ./programs/projecteur.nix ./programs/proxychains.nix ./programs/qdmr.nix ./programs/qt5ct.nix -- cgit 1.4.1 From e98a8367ecfa30b125bdf31fb5c66b137d3d31ac Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Tue, 10 Oct 2023 20:56:45 +0200 Subject: jitterentropy-rngd: init at 1.2.8 Add jitterentropy-rngd, a tool similar to rng-tools. While not necessarily needed, it is useful for those who want to strengthen their kernel entropy input pool by periodic insertion of an independent source. The entropy source is a NIST SP800-90B compliant non-physical true RNG source on most systems. See the jitterentropy documentation for details (http://chronox.de/jent/doc/CPU-Jitter-NPTRNG.pdf). Signed-off-by: Markus Theil --- nixos/modules/module-list.nix | 1 + .../services/security/jitterentropy-rngd.nix | 18 ++++++++++++ pkgs/by-name/ji/jitterentropy-rngd/package.nix | 34 ++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 nixos/modules/services/security/jitterentropy-rngd.nix create mode 100644 pkgs/by-name/ji/jitterentropy-rngd/package.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 811b82f28ce..c4056f15a24 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1148,6 +1148,7 @@ ./services/security/hologram-agent.nix ./services/security/hologram-server.nix ./services/security/infnoise.nix + ./services/security/jitterentropy-rngd.nix ./services/security/kanidm.nix ./services/security/munge.nix ./services/security/nginx-sso.nix diff --git a/nixos/modules/services/security/jitterentropy-rngd.nix b/nixos/modules/services/security/jitterentropy-rngd.nix new file mode 100644 index 00000000000..7bfacb5ddc5 --- /dev/null +++ b/nixos/modules/services/security/jitterentropy-rngd.nix @@ -0,0 +1,18 @@ +{ lib, config, pkgs, ... }: +let + cfg = config.services.jitterentropy-rngd; +in +{ + options.services.jitterentropy-rngd = { + enable = + lib.mkEnableOption (lib.mdDoc "jitterentropy-rngd service configuration"); + package = lib.mkPackageOptionMD pkgs "jitterentropy-rngd" { }; + }; + + config = lib.mkIf cfg.enable { + systemd.packages = [ cfg.package ]; + systemd.services."jitterentropy".wantedBy = [ "basic.target" ]; + }; + + meta.maintainers = with lib.maintainers; [ thillux ]; +} diff --git a/pkgs/by-name/ji/jitterentropy-rngd/package.nix b/pkgs/by-name/ji/jitterentropy-rngd/package.nix new file mode 100644 index 00000000000..feb7d1e2fb1 --- /dev/null +++ b/pkgs/by-name/ji/jitterentropy-rngd/package.nix @@ -0,0 +1,34 @@ +{ lib, stdenv, fetchFromGitHub }: + +stdenv.mkDerivation rec { + pname = "jitterentropy-rngd"; + version = "1.2.8"; + + src = fetchFromGitHub { + owner = "smuellerDD"; + repo = pname; + rev = "v${version}"; + hash = "sha256-LDym636ss3B1G/vrqatu9g5vbVEeDX0JQcxZ/IxGeY0="; + }; + + enableParallelBuilding = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out + make install DESTDIR= PREFIX=$out UNITDIR=$out/lib/systemd/system + + runHook postInstall + ''; + + meta = with lib; { + description = ''A random number generator, which injects entropy to the kernel''; + homepage = "https://github.com/smuellerDD/jitterentropy-rngd"; + changelog = "https://github.com/smuellerDD/jitterentropy-rngd/releases/tag/v${version}"; + license = [ licenses.gpl2Only licenses.bsd3 ]; + platforms = platforms.linux; + maintainers = with maintainers; [ thillux ]; + mainProgram = "jitterentropy-rngd"; + }; +} -- cgit 1.4.1 From 95856e526efd96e33cc021eb939e0529a0caa74d Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 19 Oct 2023 01:39:17 +0200 Subject: nixos/homeassistant-satellite: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + .../home-automation/homeassistant-satellite.nix | 225 +++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 nixos/modules/services/home-automation/homeassistant-satellite.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index d74dc5b93cd..bb659b3cc87 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -76,6 +76,8 @@ - [Jool](https://nicmx.github.io/Jool/en/index.html), a kernelspace NAT64 and SIIT implementation, providing translation between IPv4 and IPv6. Available as [networking.jool.enable](#opt-networking.jool.enable). +- [Home Assistant Satellite], a streaming audio satellite for Home Assistant voice pipelines, where you can reuse existing mic/speaker hardware. Available as [services.homeassistant-satellite](#opt-services.homeassistant-satellite.enable). + - [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services. - [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c248aa6f976..604f53283a1 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -556,6 +556,7 @@ ./services/home-automation/esphome.nix ./services/home-automation/evcc.nix ./services/home-automation/home-assistant.nix + ./services/home-automation/homeassistant-satellite.nix ./services/home-automation/zigbee2mqtt.nix ./services/logging/SystemdJournal2Gelf.nix ./services/logging/awstats.nix diff --git a/nixos/modules/services/home-automation/homeassistant-satellite.nix b/nixos/modules/services/home-automation/homeassistant-satellite.nix new file mode 100644 index 00000000000..e3f0617cf01 --- /dev/null +++ b/nixos/modules/services/home-automation/homeassistant-satellite.nix @@ -0,0 +1,225 @@ +{ config +, lib +, pkgs +, ... +}: + +let + cfg = config.services.homeassistant-satellite; + + inherit (lib) + escapeShellArg + escapeShellArgs + mkOption + mdDoc + mkEnableOption + mkIf + mkPackageOptionMD + types + ; + + inherit (builtins) + toString + ; + + # override the package with the relevant vad dependencies + package = cfg.package.overridePythonAttrs (oldAttrs: { + propagatedBuildInputs = oldAttrs.propagatedBuildInputs + ++ lib.optional (cfg.vad == "webrtcvad") cfg.package.optional-dependencies.webrtc + ++ lib.optional (cfg.vad == "silero") cfg.package.optional-dependencies.silerovad + ++ lib.optional (cfg.pulseaudio.enable) cfg.package.optional-dependencies.pulseaudio; + }); + +in + +{ + meta.buildDocsInSandbox = false; + + options.services.homeassistant-satellite = with types; { + enable = mkEnableOption (mdDoc "Home Assistant Satellite"); + + package = mkPackageOptionMD pkgs "homeassistant-satellite" { }; + + user = mkOption { + type = str; + example = "alice"; + description = mdDoc '' + User to run homeassistant-satellite under. + ''; + }; + + group = mkOption { + type = str; + default = "users"; + description = mdDoc '' + Group to run homeassistant-satellite under. + ''; + }; + + host = mkOption { + type = str; + example = "home-assistant.local"; + description = mdDoc '' + Hostname on which your Home Assistant instance can be reached. + ''; + }; + + port = mkOption { + type = port; + example = 8123; + description = mdDoc '' + Port on which your Home Assistance can be reached. + ''; + apply = toString; + }; + + protocol = mkOption { + type = enum [ "http" "https" ]; + default = "http"; + example = "https"; + description = mdDoc '' + The transport protocol used to connect to Home Assistant. + ''; + }; + + tokenFile = mkOption { + type = path; + example = "/run/keys/hass-token"; + description = mdDoc '' + Path to a file containing a long-lived access token for your Home Assistant instance. + ''; + apply = escapeShellArg; + }; + + sounds = { + awake = mkOption { + type = nullOr str; + default = null; + description = mdDoc '' + Audio file to play when the wake word is detected. + ''; + }; + + done = mkOption { + type = nullOr str; + default = null; + description = mdDoc '' + Audio file to play when the voice command is done. + ''; + }; + }; + + vad = mkOption { + type = enum [ "disabled" "webrtcvad" "silero" ]; + default = "disabled"; + example = "silero"; + description = mdDoc '' + Voice activity detection model. With `disabled` sound will be transmitted continously. + ''; + }; + + pulseaudio = { + enable = mkEnableOption "recording/playback via PulseAudio or PipeWire"; + + socket = mkOption { + type = nullOr str; + default = null; + example = "/run/user/1000/pulse/native"; + description = mdDoc '' + Path or hostname to connect with the PulseAudio server. + ''; + }; + + duckingVolume = mkOption { + type = nullOr float; + default = null; + example = 0.4; + description = mdDoc '' + Reduce output volume (between 0 and 1) to this percentage value while recording. + ''; + }; + + echoCancellation = mkEnableOption "acoustic echo cancellation"; + }; + + extraArgs = mkOption { + type = listOf str; + default = [ ]; + description = mdDoc '' + Extra arguments to pass to the commandline. + ''; + apply = escapeShellArgs; + }; + }; + + config = mkIf cfg.enable { + systemd.services."homeassistant-satellite" = { + description = "Home Assistant Satellite"; + after = [ + "network-online.target" + ]; + wants = [ + "network-online.target" + ]; + wantedBy = [ + "multi-user.target" + ]; + path = with pkgs; [ + ffmpeg-headless + ] ++ lib.optionals (!cfg.pulseaudio.enable) [ + alsa-utils + ]; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + # https://github.com/rhasspy/hassio-addons/blob/master/assist_microphone/rootfs/etc/s6-overlay/s6-rc.d/assist_microphone/run + ExecStart = '' + ${package}/bin/homeassistant-satellite \ + --host ${cfg.host} \ + --port ${cfg.port} \ + --protocol ${cfg.protocol} \ + --token-file ${cfg.tokenFile} \ + --vad ${cfg.vad} \ + ${lib.optionalString cfg.pulseaudio.enable "--pulseaudio"}${lib.optionalString (cfg.pulseaudio.socket != null) "=${cfg.pulseaudio.socket}"} \ + ${lib.optionalString (cfg.pulseaudio.enable && cfg.pulseaudio.duckingVolume != null) "--ducking-volume=${toString cfg.pulseaudio.duckingVolume}"} \ + ${lib.optionalString (cfg.pulseaudio.enable && cfg.pulseaudio.echoCancellation) "--echo-cancel"} \ + ${lib.optionalString (cfg.sounds.awake != null) "--awake-sound=${toString cfg.sounds.awake}"} \ + ${lib.optionalString (cfg.sounds.done != null) "--done-sound=${toString cfg.sounds.done}"} \ + ${cfg.extraArgs} + ''; + CapabilityBoundingSet = ""; + DeviceAllow = ""; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = false; # onnxruntime/capi/onnxruntime_pybind11_state.so: cannot enable executable stack as shared object requires: Operation not permitted + PrivateDevices = true; + PrivateUsers = true; + ProtectHome = false; # Would deny access to local pulse/pipewire server + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectProc = "invisible"; + ProcSubset = "all"; # Error in cpuinfo: failed to parse processor information from /proc/cpuinfo + Restart = "always"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SupplementaryGroups = [ + "audio" + ]; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; + UMask = "0077"; + }; + }; + }; +} -- cgit 1.4.1 From 8a8ec36615daecf2705cab80c3a926a0590eefff Mon Sep 17 00:00:00 2001 From: Bjørn Forsman Date: Sun, 15 Oct 2023 16:32:44 +0200 Subject: Revert "ddclient: remove package and module on upstream maintainer request" This reverts commit d35df28f65208764f6f94ba330c98615d95b934c. Upstream ddclient has new maintainers and made a new release (update in next commit(s)). --- nixos/modules/misc/ids.nix | 4 +- nixos/modules/module-list.nix | 1 + nixos/modules/rename.nix | 1 - nixos/modules/services/networking/ddclient.nix | 234 +++++++++++++++++++++++++ pkgs/tools/networking/ddclient/default.nix | 45 +++++ pkgs/top-level/aliases.nix | 1 - pkgs/top-level/all-packages.nix | 2 + 7 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 nixos/modules/services/networking/ddclient.nix create mode 100644 pkgs/tools/networking/ddclient/default.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index dc59ccb357d..5b278b5e806 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -69,7 +69,7 @@ in #dialout = 27; # unused polkituser = 28; #utmp = 29; # unused - # ddclient = 30; # software removed + # ddclient = 30; # converted to DynamicUser = true davfs2 = 31; disnix = 33; osgi = 34; @@ -394,7 +394,7 @@ in dialout = 27; #polkituser = 28; # currently unused, polkitd doesn't need a group utmp = 29; - # ddclient = 30; # software removed + # ddclient = 30; # converted to DynamicUser = true davfs2 = 31; disnix = 33; osgi = 34; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2c06f493172..79918f71f7b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -884,6 +884,7 @@ ./services/networking/dae.nix ./services/networking/dante.nix ./services/networking/deconz.nix + ./services/networking/ddclient.nix ./services/networking/dhcpcd.nix ./services/networking/dnscache.nix ./services/networking/dnscrypt-proxy2.nix diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 408c515044c..0fbb2351f98 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -54,7 +54,6 @@ in (mkRemovedOptionModule [ "services" "chronos" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "couchpotato" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "dd-agent" ] "dd-agent was removed from nixpkgs in favor of the newer datadog-agent.") - (mkRemovedOptionModule [ "services" "ddclient" ] "ddclient has been removed on the request of the upstream maintainer because it is unmaintained and has bugs. Please switch to a different software like `inadyn` or `knsupdate`.") # Added 2023-07-04 (mkRemovedOptionModule [ "services" "dnscrypt-proxy" ] "Use services.dnscrypt-proxy2 instead") (mkRemovedOptionModule [ "services" "exhibitor" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "firefox" "syncserver" ] "The corresponding package was removed from nixpkgs.") diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix new file mode 100644 index 00000000000..4985a2dd4b2 --- /dev/null +++ b/nixos/modules/services/networking/ddclient.nix @@ -0,0 +1,234 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.ddclient; + boolToStr = bool: if bool then "yes" else "no"; + dataDir = "/var/lib/ddclient"; + StateDirectory = builtins.baseNameOf dataDir; + RuntimeDirectory = StateDirectory; + + configFile' = pkgs.writeText "ddclient.conf" '' + # This file can be used as a template for configFile or is automatically generated by Nix options. + cache=${dataDir}/ddclient.cache + foreground=YES + use=${cfg.use} + login=${cfg.username} + password=${if cfg.protocol == "nsupdate" then "/run/${RuntimeDirectory}/ddclient.key" else "@password_placeholder@"} + protocol=${cfg.protocol} + ${lib.optionalString (cfg.script != "") "script=${cfg.script}"} + ${lib.optionalString (cfg.server != "") "server=${cfg.server}"} + ${lib.optionalString (cfg.zone != "") "zone=${cfg.zone}"} + ssl=${boolToStr cfg.ssl} + wildcard=YES + quiet=${boolToStr cfg.quiet} + verbose=${boolToStr cfg.verbose} + ${cfg.extraConfig} + ${lib.concatStringsSep "," cfg.domains} + ''; + configFile = if (cfg.configFile != null) then cfg.configFile else configFile'; + + preStart = '' + install --mode=600 --owner=$USER ${configFile} /run/${RuntimeDirectory}/ddclient.conf + ${lib.optionalString (cfg.configFile == null) (if (cfg.protocol == "nsupdate") then '' + install --mode=600 --owner=$USER ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key + '' else if (cfg.passwordFile != null) then '' + "${pkgs.replace-secret}/bin/replace-secret" "@password_placeholder@" "${cfg.passwordFile}" "/run/${RuntimeDirectory}/ddclient.conf" + '' else '' + sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf + '')} + ''; + +in + +with lib; + +{ + + imports = [ + (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" ] "") + ]; + + ###### interface + + options = { + + services.ddclient = with lib.types; { + + enable = mkOption { + default = false; + type = bool; + description = lib.mdDoc '' + Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org). + ''; + }; + + package = mkOption { + type = package; + default = pkgs.ddclient; + defaultText = lib.literalExpression "pkgs.ddclient"; + description = lib.mdDoc '' + The ddclient executable package run by the service. + ''; + }; + + domains = mkOption { + default = [ "" ]; + type = listOf str; + description = lib.mdDoc '' + Domain name(s) to synchronize. + ''; + }; + + username = 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 = ""; + type = str; + description = lib.mdDoc '' + User name. + ''; + }; + + passwordFile = mkOption { + default = null; + type = nullOr str; + description = lib.mdDoc '' + A file containing the password or a TSIG key in named format when using the nsupdate protocol. + ''; + }; + + interval = mkOption { + default = "10min"; + type = str; + description = lib.mdDoc '' + The interval at which to run the check and update. + See {command}`man 7 systemd.time` for the format. + ''; + }; + + configFile = mkOption { + default = null; + type = nullOr path; + description = lib.mdDoc '' + Path to configuration file. + When set this overrides the generated configuration from module options. + ''; + example = "/root/nixos/secrets/ddclient.conf"; + }; + + protocol = mkOption { + default = "dyndns2"; + type = str; + description = lib.mdDoc '' + Protocol to use with dynamic DNS provider (see https://sourceforge.net/p/ddclient/wiki/protocols). + ''; + }; + + server = mkOption { + default = ""; + type = str; + description = lib.mdDoc '' + Server address. + ''; + }; + + ssl = mkOption { + default = true; + type = bool; + description = lib.mdDoc '' + Whether to use SSL/TLS to connect to dynamic DNS provider. + ''; + }; + + quiet = mkOption { + default = false; + type = bool; + description = lib.mdDoc '' + Print no messages for unnecessary updates. + ''; + }; + + script = mkOption { + default = ""; + type = str; + description = lib.mdDoc '' + script as required by some providers. + ''; + }; + + use = mkOption { + default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '"; + type = str; + description = lib.mdDoc '' + Method to determine the IP address to send to the dynamic DNS provider. + ''; + }; + + verbose = mkOption { + default = false; + type = bool; + description = lib.mdDoc '' + Print verbose information. + ''; + }; + + zone = mkOption { + default = ""; + type = str; + description = lib.mdDoc '' + zone as required by some providers. + ''; + }; + + extraConfig = mkOption { + default = ""; + type = lines; + description = lib.mdDoc '' + Extra configuration. Contents will be added verbatim to the configuration file. + + ::: {.note} + `daemon` should not be added here because it does not work great with the systemd-timer approach the service uses. + ::: + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf config.services.ddclient.enable { + systemd.services.ddclient = { + description = "Dynamic DNS Client"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + restartTriggers = optional (cfg.configFile != null) cfg.configFile; + path = lib.optional (lib.hasPrefix "if," cfg.use) pkgs.iproute2; + + serviceConfig = { + DynamicUser = true; + RuntimeDirectoryMode = "0700"; + inherit RuntimeDirectory; + inherit StateDirectory; + Type = "oneshot"; + ExecStartPre = "!${pkgs.writeShellScript "ddclient-prestart" preStart}"; + ExecStart = "${lib.getBin cfg.package}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf"; + }; + }; + + systemd.timers.ddclient = { + description = "Run ddclient"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = cfg.interval; + OnUnitInactiveSec = cfg.interval; + }; + }; + }; +} diff --git a/pkgs/tools/networking/ddclient/default.nix b/pkgs/tools/networking/ddclient/default.nix new file mode 100644 index 00000000000..b39af193010 --- /dev/null +++ b/pkgs/tools/networking/ddclient/default.nix @@ -0,0 +1,45 @@ +{ lib, fetchFromGitHub, perlPackages, autoreconfHook, iproute2, perl }: + +perlPackages.buildPerlPackage rec { + pname = "ddclient"; + version = "3.10.0"; + + outputs = [ "out" ]; + + src = fetchFromGitHub { + owner = "ddclient"; + repo = "ddclient"; + rev = "v${version}"; + sha256 = "sha256-wWUkjXwVNZRJR1rXPn3IkDRi9is9vsRuNC/zq8RpB1E="; + }; + + postPatch = '' + touch Makefile.PL + ''; + + nativeBuildInputs = [ autoreconfHook ]; + + buildInputs = with perlPackages; [ IOSocketINET6 IOSocketSSL JSONPP ]; + + installPhase = '' + runHook preInstall + + # patch sheebang ddclient script which only exists after buildPhase + preConfigure + install -Dm755 ddclient $out/bin/ddclient + install -Dm644 -t $out/share/doc/ddclient COP* README.* ChangeLog.md + + runHook postInstall + ''; + + # TODO: run upstream tests + doCheck = false; + + meta = with lib; { + description = "Client for updating dynamic DNS service entries"; + homepage = "https://ddclient.net/"; + license = licenses.gpl2Plus; + platforms = platforms.linux; + maintainers = with maintainers; [ SuperSandro2000 ]; + }; +} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 9d2e755ca14..4e52ec42d82 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -92,7 +92,6 @@ mapAliases ({ bird2 = bird; # Added 2022-02-21 bitwig-studio1 = throw "bitwig-studio1 has been removed, you can upgrade to 'bitwig-studio'"; # Added 2023-01-03 bitwig-studio2 = throw "bitwig-studio2 has been removed, you can upgrade to 'bitwig-studio'"; # Added 2023-01-03 - ddclient = throw "ddclient has been removed on the request of the upstream maintainer because it is unmaintained and has bugs. Please switch to a different software like `inadyn` or `knsupdate`."; # Added 2023-07-04 bluezFull = throw "'bluezFull' has been renamed to/replaced by 'bluez'"; # Converted to throw 2023-09-10 boost168 = throw "boost168 has been deprecated in favor of the latest version"; # Added 2023-06-08 boost169 = throw "boost169 has been deprecated in favor of the latest version"; # Added 2023-06-08 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index dc67c15628c..9a56cba3b54 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7425,6 +7425,8 @@ with pkgs; ddcutil = callPackage ../tools/misc/ddcutil { }; + ddclient = callPackage ../tools/networking/ddclient { }; + dd_rescue = callPackage ../tools/system/dd_rescue { }; ddh = callPackage ../tools/system/ddh { }; -- cgit 1.4.1 From 77f7b5a3e5cf65b4b31204aae8d205a771ec990e Mon Sep 17 00:00:00 2001 From: dadada Date: Sat, 8 Jul 2023 01:44:42 +0200 Subject: nixos/soft-serve: init This adds a NixOS module for Soft Serve, a tasty, self-hostable Git server for the command line. The module has a test that checks some basic things like creating users, creating a repo and cloning it. Co-authored-by: Sandro --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/misc/soft-serve.nix | 99 +++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/soft-serve.nix | 102 ++++++++++++++++++++++ pkgs/servers/soft-serve/default.nix | 4 +- 6 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/services/misc/soft-serve.nix create mode 100644 nixos/tests/soft-serve.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 38c89668f84..13648364e13 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -113,6 +113,8 @@ - [virt-manager](https://virt-manager.org/), an UI for managing virtual machines in libvirt, is now available as `programs.virt-manager`. +- [Soft Serve](https://github.com/charmbracelet/soft-serve), a tasty, self-hostable Git server for the command line. Available as [services.soft-serve](#opt-services.soft-serve.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - `network-online.target` has been fixed to no longer time out for systems with `networking.useDHCP = true` and `networking.useNetworkd = true`. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 79918f71f7b..69f2a5a557c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -730,6 +730,7 @@ ./services/misc/signald.nix ./services/misc/siproxd.nix ./services/misc/snapper.nix + ./services/misc/soft-serve.nix ./services/misc/sonarr.nix ./services/misc/sourcehut ./services/misc/spice-vdagentd.nix diff --git a/nixos/modules/services/misc/soft-serve.nix b/nixos/modules/services/misc/soft-serve.nix new file mode 100644 index 00000000000..0f246493880 --- /dev/null +++ b/nixos/modules/services/misc/soft-serve.nix @@ -0,0 +1,99 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.soft-serve; + configFile = format.generate "config.yaml" cfg.settings; + format = pkgs.formats.yaml { }; + docUrl = "https://charm.sh/blog/self-hosted-soft-serve/"; + stateDir = "/var/lib/soft-serve"; +in +{ + options = { + services.soft-serve = { + enable = mkEnableOption "Enable soft-serve service"; + + package = mkPackageOption pkgs "soft-serve" { }; + + settings = mkOption { + type = format.type; + default = { }; + description = mdDoc '' + The contents of the configuration file. + + See <${docUrl}>. + ''; + example = literalExpression '' + { + name = "dadada's repos"; + log_format = "text"; + ssh = { + listen_addr = ":23231"; + public_url = "ssh://localhost:23231"; + max_timeout = 30; + idle_timeout = 120; + }; + stats.listen_addr = ":23233"; + } + ''; + }; + }; + }; + + config = mkIf cfg.enable { + + systemd.tmpfiles.rules = [ + # The config file has to be inside the state dir + "L+ ${stateDir}/config.yaml - - - - ${configFile}" + ]; + + systemd.services.soft-serve = { + description = "Soft Serve git server"; + documentation = [ docUrl ]; + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment.SOFT_SERVE_DATA_PATH = stateDir; + + serviceConfig = { + Type = "simple"; + DynamicUser = true; + Restart = "always"; + ExecStart = "${getExe cfg.package} serve"; + StateDirectory = "soft-serve"; + WorkingDirectory = stateDir; + RuntimeDirectory = "soft-serve"; + RuntimeDirectoryMode = "0750"; + ProcSubset = "pid"; + ProtectProc = "invisible"; + UMask = "0027"; + CapabilityBoundingSet = ""; + ProtectHome = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RemoveIPC = true; + PrivateMounts = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io @reboot @setuid @swap" + ]; + }; + }; + }; + + meta.maintainers = [ maintainers.dadada ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 33f8abf6ccd..59da5827a1b 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -732,6 +732,7 @@ in { snapper = handleTest ./snapper.nix {}; snipe-it = runTest ./web-apps/snipe-it.nix; soapui = handleTest ./soapui.nix {}; + soft-serve = handleTest ./soft-serve.nix {}; sogo = handleTest ./sogo.nix {}; solanum = handleTest ./solanum.nix {}; sonarr = handleTest ./sonarr.nix {}; diff --git a/nixos/tests/soft-serve.nix b/nixos/tests/soft-serve.nix new file mode 100644 index 00000000000..1c4cb4c9581 --- /dev/null +++ b/nixos/tests/soft-serve.nix @@ -0,0 +1,102 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: +let + inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey; + sshPort = 8231; + httpPort = 8232; + statsPort = 8233; + gitPort = 8418; +in +{ + name = "soft-serve"; + meta.maintainers = with lib.maintainers; [ dadada ]; + nodes = { + client = { pkgs, ... }: { + environment.systemPackages = with pkgs; [ + curl + git + openssh + ]; + environment.etc.sshKey = { + source = snakeOilPrivateKey; + mode = "0600"; + }; + }; + + server = + { config, ... }: + { + services.soft-serve = { + enable = true; + settings = { + name = "TestServer"; + ssh.listen_addr = ":${toString sshPort}"; + git.listen_addr = ":${toString gitPort}"; + http.listen_addr = ":${toString httpPort}"; + stats.listen_addr = ":${toString statsPort}"; + initial_admin_keys = [ snakeOilPublicKey ]; + }; + }; + networking.firewall.allowedTCPPorts = [ sshPort httpPort statsPort ]; + }; + }; + + testScript = + { ... }: + '' + SSH_PORT = ${toString sshPort} + HTTP_PORT = ${toString httpPort} + STATS_PORT = ${toString statsPort} + KEY = "${snakeOilPublicKey}" + SSH_KEY = "/etc/sshKey" + SSH_COMMAND = f"ssh -p {SSH_PORT} -i {SSH_KEY} -o StrictHostKeyChecking=no" + TEST_DIR = "/tmp/test" + GIT = f"git -C {TEST_DIR}" + + for machine in client, server: + machine.wait_for_unit("network.target") + + server.wait_for_unit("soft-serve.service") + server.wait_for_open_port(SSH_PORT) + + with subtest("Get info"): + status, test = client.execute(f"{SSH_COMMAND} server info") + if status != 0: + raise Exception("Failed to get SSH info") + key = " ".join(KEY.split(" ")[0:2]) + if not key in test: + raise Exception("Admin key must be configured correctly") + + with subtest("Create user"): + client.succeed(f"{SSH_COMMAND} server user create beatrice") + client.succeed(f"{SSH_COMMAND} server user info beatrice") + + with subtest("Create repo"): + client.succeed(f"git init {TEST_DIR}") + client.succeed(f"{GIT} config --global user.email you@example.com") + client.succeed(f"touch {TEST_DIR}/foo") + client.succeed(f"{GIT} add foo") + client.succeed(f"{GIT} commit --allow-empty -m test") + client.succeed(f"{GIT} remote add origin git@server:test") + client.succeed(f"GIT_SSH_COMMAND='{SSH_COMMAND}' {GIT} push -u origin master") + client.execute("rm -r /tmp/test") + + server.wait_for_open_port(HTTP_PORT) + + with subtest("Clone over HTTP"): + client.succeed(f"curl --connect-timeout 10 http://server:{HTTP_PORT}/") + client.succeed(f"git clone http://server:{HTTP_PORT}/test /tmp/test") + client.execute("rm -r /tmp/test") + + with subtest("Clone over SSH"): + client.succeed(f"GIT_SSH_COMMAND='{SSH_COMMAND}' git clone git@server:test /tmp/test") + client.execute("rm -r /tmp/test") + + with subtest("Get stats over HTTP"): + server.wait_for_open_port(STATS_PORT) + status, test = client.execute(f"curl --connect-timeout 10 http://server:{STATS_PORT}/metrics") + if status != 0: + raise Exception("Failed to get metrics from status port") + if not "go_gc_duration_seconds_count" in test: + raise Exception("Metrics did not contain key 'go_gc_duration_seconds_count'") + ''; +}) diff --git a/pkgs/servers/soft-serve/default.nix b/pkgs/servers/soft-serve/default.nix index 01a5ea9d6dd..2cfd41f7caf 100644 --- a/pkgs/servers/soft-serve/default.nix +++ b/pkgs/servers/soft-serve/default.nix @@ -1,4 +1,4 @@ -{ lib, buildGoModule, fetchFromGitHub, makeWrapper, git, bash }: +{ lib, buildGoModule, fetchFromGitHub, makeWrapper, nixosTests, git, bash }: buildGoModule rec { pname = "soft-serve"; @@ -26,6 +26,8 @@ buildGoModule rec { --prefix PATH : "${lib.makeBinPath [ git bash ]}" ''; + passthru.tests = nixosTests.soft-serve; + meta = with lib; { description = "A tasty, self-hosted Git server for the command line"; homepage = "https://github.com/charmbracelet/soft-serve"; -- cgit 1.4.1 From d1df9108ba701b9a02945182e60da0a0201d2464 Mon Sep 17 00:00:00 2001 From: Rishi Desai Date: Tue, 25 Jul 2023 12:45:41 -0500 Subject: nixos/fanout: init fanout oneshot module --- nixos/modules/config/fanout.nix | 49 +++++++++++++++++++++++++++++++++++++++++ nixos/modules/module-list.nix | 1 + 2 files changed, 50 insertions(+) create mode 100644 nixos/modules/config/fanout.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/config/fanout.nix b/nixos/modules/config/fanout.nix new file mode 100644 index 00000000000..60ee145f19a --- /dev/null +++ b/nixos/modules/config/fanout.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.fanout; + mknodCmds = n: lib.lists.imap0 (i: s: + "mknod /dev/fanout${builtins.toString i} c $MAJOR ${builtins.toString i}" + ) (lib.lists.replicate n ""); +in +{ + options.services.fanout = { + enable = lib.mkEnableOption (lib.mdDoc "fanout"); + fanoutDevices = lib.mkOption { + type = lib.types.int; + default = 1; + description = "Number of /dev/fanout devices"; + }; + bufferSize = lib.mkOption { + type = lib.types.int; + default = 16384; + description = "Size of /dev/fanout buffer in bytes"; + }; + }; + + config = lib.mkIf cfg.enable { + boot.extraModulePackages = [ config.boot.kernelPackages.fanout.out ]; + + boot.kernelModules = [ "fanout" ]; + + boot.extraModprobeConfig = '' + options fanout buffersize=${builtins.toString cfg.bufferSize} + ''; + + systemd.services.fanout = { + description = "Bring up /dev/fanout devices"; + script = '' + MAJOR=$(${pkgs.gnugrep}/bin/grep fanout /proc/devices | ${pkgs.gawk}/bin/awk '{print $1}') + ${lib.strings.concatLines (mknodCmds cfg.fanoutDevices)} + ''; + + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "oneshot"; + User = "root"; + RemainAfterExit = "yes"; + Restart = "no"; + }; + }; + }; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b32783d4e2e..395a638033f 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -2,6 +2,7 @@ ./config/appstream.nix ./config/console.nix ./config/debug-info.nix + ./config/fanout.nix ./config/fonts/fontconfig.nix ./config/fonts/fontdir.nix ./config/fonts/ghostscript.nix -- cgit 1.4.1 From a98c93341296b085085e1a875010455d1da5f513 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Wed, 4 Oct 2023 14:53:28 +0200 Subject: nixos/hardware/cpu/intel/msr: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/hardware/cpu/x86-msr.nix | 91 +++++++++++++++++++++++ nixos/modules/module-list.nix | 1 + 3 files changed, 94 insertions(+) create mode 100644 nixos/modules/hardware/cpu/x86-msr.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 688d7036d45..79b2b3a73fe 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -493,3 +493,5 @@ The module update takes care of the new config syntax and the data itself (user - The `electron` packages now places its application files in `$out/libexec/electron` instead of `$out/lib/electron`. Packages using electron-builder will fail to build and need to be adjusted by changing `lib` to `libexec`. - `teleport` has been upgraded from major version 12 to major version 14. Please see upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/) and release notes for versions [13](https://goteleport.com/docs/changelog/#1300-050823) and [14](https://goteleport.com/docs/changelog/#1400-092023). Note that Teleport does not officially support upgrades across more than one major version at a time. If you're running Teleport server components, it is recommended to first upgrade to an intermediate 13.x version by setting `services.teleport.package = pkgs.teleport_13`. Afterwards, this option can be removed to upgrade to the default version (14). + +- The Linux kernel module `msr` (see [`msr(4)`](https://man7.org/linux/man-pages/man4/msr.4.html)), which provides an interface to read and write the model-specific registers (MSRs) of an x86 CPU, can now be configured via `hardware.cpu.x86.msr`. diff --git a/nixos/modules/hardware/cpu/x86-msr.nix b/nixos/modules/hardware/cpu/x86-msr.nix new file mode 100644 index 00000000000..554bec1b7db --- /dev/null +++ b/nixos/modules/hardware/cpu/x86-msr.nix @@ -0,0 +1,91 @@ +{ lib +, config +, options +, ... +}: +let + inherit (builtins) hasAttr; + inherit (lib) mkIf mdDoc; + cfg = config.hardware.cpu.x86.msr; + opt = options.hardware.cpu.x86.msr; + defaultGroup = "msr"; + isDefaultGroup = cfg.group == defaultGroup; + set = "to set for devices of the `msr` kernel subsystem."; + + # Generates `foo=bar` parameters to pass to the kernel. + # If `module = baz` is passed, generates `baz.foo=bar`. + # Adds double quotes on demand to handle `foo="bar baz"`. + kernelParam = { module ? null }: name: value: + assert lib.asserts.assertMsg (!lib.strings.hasInfix "=" name) "kernel parameter cannot have '=' in name"; + let + key = (if module == null then "" else module + ".") + name; + valueString = lib.generators.mkValueStringDefault {} value; + quotedValueString = if lib.strings.hasInfix " " valueString + then lib.strings.escape ["\""] valueString + else valueString; + in "${key}=${quotedValueString}"; + msrKernelParam = kernelParam { module = "msr"; }; +in +{ + options.hardware.cpu.x86.msr = with lib.options; with lib.types; { + enable = mkEnableOption (mdDoc "the `msr` (Model-Specific Registers) kernel module and configure `udev` rules for its devices (usually `/dev/cpu/*/msr`)"); + owner = mkOption { + type = str; + default = "root"; + example = "nobody"; + description = mdDoc "Owner ${set}"; + }; + group = mkOption { + type = str; + default = defaultGroup; + example = "nobody"; + description = mdDoc "Group ${set}"; + }; + mode = mkOption { + type = str; + default = "0640"; + example = "0660"; + description = mdDoc "Mode ${set}"; + }; + settings = mkOption { + type = submodule { + freeformType = attrsOf (oneOf [ bool int str ]); + options.allow-writes = mkOption { + type = nullOr (enum ["on" "off"]); + default = null; + description = "Whether to allow writes to MSRs (`\"on\"`) or not (`\"off\"`)."; + }; + }; + default = {}; + description = "Parameters for the `msr` kernel module."; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = hasAttr cfg.owner config.users.users; + message = "Owner '${cfg.owner}' set in `${opt.owner}` is not configured via `${options.users.users}.\"${cfg.owner}\"`."; + } + { + assertion = isDefaultGroup || (hasAttr cfg.group config.users.groups); + message = "Group '${cfg.group}' set in `${opt.group}` is not configured via `${options.users.groups}.\"${cfg.group}\"`."; + } + ]; + + boot = { + kernelModules = [ "msr" ]; + kernelParams = lib.attrsets.mapAttrsToList msrKernelParam (lib.attrsets.filterAttrs (_: value: value != null) cfg.settings); + }; + + users.groups.${cfg.group} = mkIf isDefaultGroup { }; + + services.udev.extraRules = '' + SUBSYSTEM=="msr", OWNER="${cfg.owner}", GROUP="${cfg.group}", MODE="${cfg.mode}" + ''; + }; + + meta = with lib; { + maintainers = with maintainers; [ lorenzleutgeb ]; + }; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 395a638033f..4526987b636 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -55,6 +55,7 @@ ./hardware/cpu/amd-sev.nix ./hardware/cpu/intel-microcode.nix ./hardware/cpu/intel-sgx.nix + ./hardware/cpu/x86-msr.nix ./hardware/decklink.nix ./hardware/device-tree.nix ./hardware/digitalbitbox.nix -- cgit 1.4.1 From d147d7feed63ba43e80a103d278d5ad4bb12b1fd Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Sun, 8 Oct 2023 20:22:45 +0000 Subject: nixos/spice-autorandr: init --- nixos/modules/module-list.nix | 1 + nixos/modules/services/misc/spice-autorandr.nix | 26 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 nixos/modules/services/misc/spice-autorandr.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 811b82f28ce..20a7d06d0f9 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -731,6 +731,7 @@ ./services/misc/snapper.nix ./services/misc/sonarr.nix ./services/misc/sourcehut + ./services/misc/spice-autorandr.nix ./services/misc/spice-vdagentd.nix ./services/misc/spice-webdavd.nix ./services/misc/ssm-agent.nix diff --git a/nixos/modules/services/misc/spice-autorandr.nix b/nixos/modules/services/misc/spice-autorandr.nix new file mode 100644 index 00000000000..8437441c752 --- /dev/null +++ b/nixos/modules/services/misc/spice-autorandr.nix @@ -0,0 +1,26 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.spice-autorandr; +in +{ + options = { + services.spice-autorandr = { + enable = lib.mkEnableOption (lib.mdDoc "spice-autorandr service that will automatically resize display to match SPICE client window size."); + package = lib.mkPackageOptionMD pkgs "spice-autorandr" { }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.user.services.spice-autorandr = { + wantedBy = [ "default.target" ]; + after = [ "spice-vdagentd.service" ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/spice-autorandr"; + Restart = "on-failure"; + }; + }; + }; +} -- cgit 1.4.1 From ccf080ee055c620c6adc451c1b1b29a71ec0722a Mon Sep 17 00:00:00 2001 From: Anthony Roussel Date: Tue, 17 Oct 2023 23:01:15 +0200 Subject: amazon-ssm-agent: rename from ssm-agent --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 2 +- nixos/modules/services/misc/amazon-ssm-agent.nix | 78 ++++++++++ nixos/modules/services/misc/ssm-agent.nix | 73 ---------- ...le-NIC-tests-that-fail-in-the-Nix-sandbox.patch | 44 ------ ...rsion-gen-don-t-use-unnecessary-constants.patch | 46 ------ .../networking/cluster/ssm-agent/default.nix | 157 --------------------- ...le-NIC-tests-that-fail-in-the-Nix-sandbox.patch | 44 ++++++ ...rsion-gen-don-t-use-unnecessary-constants.patch | 46 ++++++ pkgs/by-name/am/amazon-ssm-agent/package.nix | 157 +++++++++++++++++++++ pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 1 - 12 files changed, 329 insertions(+), 322 deletions(-) create mode 100644 nixos/modules/services/misc/amazon-ssm-agent.nix delete mode 100644 nixos/modules/services/misc/ssm-agent.nix delete mode 100644 pkgs/applications/networking/cluster/ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch delete mode 100644 pkgs/applications/networking/cluster/ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch delete mode 100644 pkgs/applications/networking/cluster/ssm-agent/default.nix create mode 100644 pkgs/by-name/am/amazon-ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch create mode 100644 pkgs/by-name/am/amazon-ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch create mode 100644 pkgs/by-name/am/amazon-ssm-agent/package.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 9e2afe5fd20..b7b1a71c90d 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -325,6 +325,8 @@ - `ps3netsrv` has been replaced with the webman-mod fork, the executable has been renamed from `ps3netsrv++` to `ps3netsrv` and cli parameters have changed. +- `ssm-agent` package and module were renamed to `amazon-ssm-agent` to be consistent with the upstream package name. + ## Other Notable Changes {#sec-release-23.11-notable-changes} - The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 47b262bf4d9..673a87e49a1 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -625,6 +625,7 @@ ./services/matrix/matrix-sliding-sync.nix ./services/matrix/synapse.nix ./services/misc/airsonic.nix + ./services/misc/amazon-ssm-agent.nix ./services/misc/ananicy.nix ./services/misc/ankisyncd.nix ./services/misc/apache-kafka.nix @@ -741,7 +742,6 @@ ./services/misc/spice-autorandr.nix ./services/misc/spice-vdagentd.nix ./services/misc/spice-webdavd.nix - ./services/misc/ssm-agent.nix ./services/misc/sssd.nix ./services/misc/subsonic.nix ./services/misc/sundtek.nix diff --git a/nixos/modules/services/misc/amazon-ssm-agent.nix b/nixos/modules/services/misc/amazon-ssm-agent.nix new file mode 100644 index 00000000000..0be79e759c3 --- /dev/null +++ b/nixos/modules/services/misc/amazon-ssm-agent.nix @@ -0,0 +1,78 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.services.amazon-ssm-agent; + + # The SSM agent doesn't pay attention to our /etc/os-release yet, and the lsb-release tool + # in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM + # looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix. + fake-lsb-release = pkgs.writeScriptBin "lsb_release" '' + #!${pkgs.runtimeShell} + + case "$1" in + -i) echo "nixos";; + -r) echo "${config.system.nixos.version}";; + esac + ''; +in { + imports = [ + (mkRenamedOptionModule [ "services" "ssm-agent" "enable" ] [ "services" "amazon-ssm-agent" "enable" ]) + (mkRenamedOptionModule [ "services" "ssm-agent" "package" ] [ "services" "amazon-ssm-agent" "package" ]) + ]; + + options.services.amazon-ssm-agent = { + enable = mkEnableOption (lib.mdDoc "Amazon SSM agent"); + + package = mkOption { + type = types.path; + description = lib.mdDoc "The Amazon SSM agent package to use"; + default = pkgs.amazon-ssm-agent.override { overrideEtc = false; }; + defaultText = literalExpression "pkgs.amazon-ssm-agent.override { overrideEtc = false; }"; + }; + }; + + config = mkIf cfg.enable { + systemd.services.amazon-ssm-agent = { + inherit (cfg.package.meta) description; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + path = [ fake-lsb-release pkgs.coreutils ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/amazon-ssm-agent"; + KillMode = "process"; + # We want this restating pretty frequently. It could be our only means + # of accessing the instance. + Restart = "always"; + RestartSec = "1min"; + }; + }; + + # Add user that Session Manager needs, and give it sudo. + # This is consistent with Amazon Linux 2 images. + security.sudo.extraRules = [ + { + users = [ "ssm-user" ]; + commands = [ + { + command = "ALL"; + options = [ "NOPASSWD" ]; + } + ]; + } + ]; + # On Amazon Linux 2 images, the ssm-user user is pretty much a + # normal user with its own group. We do the same. + users.groups.ssm-user = {}; + users.users.ssm-user = { + isNormalUser = true; + group = "ssm-user"; + }; + + environment.etc."amazon/ssm/seelog.xml".source = "${cfg.package}/seelog.xml.template"; + + environment.etc."amazon/ssm/amazon-ssm-agent.json".source = "${cfg.package}/etc/amazon/ssm/amazon-ssm-agent.json.template"; + + }; +} diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix deleted file mode 100644 index d1f371c2bd6..00000000000 --- a/nixos/modules/services/misc/ssm-agent.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; -let - cfg = config.services.ssm-agent; - - # The SSM agent doesn't pay attention to our /etc/os-release yet, and the lsb-release tool - # in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM - # looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix. - fake-lsb-release = pkgs.writeScriptBin "lsb_release" '' - #!${pkgs.runtimeShell} - - case "$1" in - -i) echo "nixos";; - -r) echo "${config.system.nixos.version}";; - esac - ''; -in { - options.services.ssm-agent = { - enable = mkEnableOption (lib.mdDoc "AWS SSM agent"); - - package = mkOption { - type = types.path; - description = lib.mdDoc "The SSM agent package to use"; - default = pkgs.ssm-agent.override { overrideEtc = false; }; - defaultText = literalExpression "pkgs.ssm-agent.override { overrideEtc = false; }"; - }; - }; - - config = mkIf cfg.enable { - systemd.services.ssm-agent = { - inherit (cfg.package.meta) description; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - path = [ fake-lsb-release pkgs.coreutils ]; - serviceConfig = { - ExecStart = "${cfg.package}/bin/amazon-ssm-agent"; - KillMode = "process"; - # We want this restating pretty frequently. It could be our only means - # of accessing the instance. - Restart = "always"; - RestartSec = "1min"; - }; - }; - - # Add user that Session Manager needs, and give it sudo. - # This is consistent with Amazon Linux 2 images. - security.sudo.extraRules = [ - { - users = [ "ssm-user" ]; - commands = [ - { - command = "ALL"; - options = [ "NOPASSWD" ]; - } - ]; - } - ]; - # On Amazon Linux 2 images, the ssm-user user is pretty much a - # normal user with its own group. We do the same. - users.groups.ssm-user = {}; - users.users.ssm-user = { - isNormalUser = true; - group = "ssm-user"; - }; - - environment.etc."amazon/ssm/seelog.xml".source = "${cfg.package}/seelog.xml.template"; - - environment.etc."amazon/ssm/amazon-ssm-agent.json".source = "${cfg.package}/etc/amazon/ssm/amazon-ssm-agent.json.template"; - - }; -} diff --git a/pkgs/applications/networking/cluster/ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch b/pkgs/applications/networking/cluster/ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch deleted file mode 100644 index 364f7653efa..00000000000 --- a/pkgs/applications/networking/cluster/ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch +++ /dev/null @@ -1,44 +0,0 @@ -From bea6307ec2a77d90d59c13940381d73ec0f05b70 Mon Sep 17 00:00:00 2001 -From: Graham Christensen -Date: Mon, 1 Mar 2021 10:57:44 -0500 -Subject: [PATCH] Disable NIC tests that fail in the Nix sandbox. - ---- - agent/managedInstances/fingerprint/fingerprint_integ_test.go | 2 ++ - agent/ssm/service_test.go | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/agent/managedInstances/fingerprint/fingerprint_integ_test.go b/agent/managedInstances/fingerprint/fingerprint_integ_test.go -index a1f969ff..631ea1f5 100644 ---- a/agent/managedInstances/fingerprint/fingerprint_integ_test.go -+++ b/agent/managedInstances/fingerprint/fingerprint_integ_test.go -@@ -28,12 +28,14 @@ func TestHostnameInfo(t *testing.T) { - } - - func TestPrimaryIpInfo(t *testing.T) { -+ t.Skip("The Nix build sandbox has no non-loopback IPs, causing this test to fail."); - ip, err := primaryIpInfo() - assert.NoError(t, err, "expected no error fetching the primary ip") - assert.NotEmpty(t, ip, "expected to fetch primary ip") - } - - func TestMacAddrInfo(t *testing.T) { -+ t.Skip("The Nix build sandbox has no non-loopback interfaces, causing this test to fail."); - mac, err := macAddrInfo() - assert.NoError(t, err, "expected no error fetching the mac addr") - assert.NotEmpty(t, mac, "expected to fetch mac address") -diff --git a/agent/ssm/service_test.go b/agent/ssm/service_test.go -index f4b34f83..d8216dba 100644 ---- a/agent/ssm/service_test.go -+++ b/agent/ssm/service_test.go -@@ -85,6 +85,7 @@ func (suite *SsmServiceTestSuite) TestUpdateEmptyInstanceInformation() { - // Test function for update instance information - // This function update the agent name, agent statuc, and agent version. - func (suite *SsmServiceTestSuite) TestUpdateInstanceInformation() { -+ suite.T().Skip("The Nix build sandbox has no interfaces for IP and MAC address reports."); - // Give mock value to test UpdateInstanceInformation, assert the error is nil, assert the log.Debug function get called. - response, err := suite.sdkService.UpdateInstanceInformation(suite.logMock, "2.2.3.2", "active", "Amazon-ssm-agent") - assert.Nil(suite.T(), err, "Err should be nil") --- -2.29.2 - diff --git a/pkgs/applications/networking/cluster/ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch b/pkgs/applications/networking/cluster/ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch deleted file mode 100644 index 234e510d3d1..00000000000 --- a/pkgs/applications/networking/cluster/ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 473e3f8544915a35b3a45c548743978b34e5310e Mon Sep 17 00:00:00 2001 -From: Cole Helbling -Date: Tue, 2 Mar 2021 00:24:00 -0800 -Subject: [PATCH] version-gen: don't use unnecessary constants - -This prevents the tool from being built with Nix, because this project -doesn't use Go modules (or something; I'm not really familiar with Go, -much less Go + Nix). ---- - agent/version/versiongenerator/version-gen.go | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/agent/version/versiongenerator/version-gen.go b/agent/version/versiongenerator/version-gen.go -index d710effc..55c9a001 100644 ---- a/agent/version/versiongenerator/version-gen.go -+++ b/agent/version/versiongenerator/version-gen.go -@@ -22,8 +22,6 @@ import ( - "path/filepath" - "strings" - "text/template" -- -- "github.com/aws/amazon-ssm-agent/agent/appconfig" - ) - - const versiongoTemplate = `// This is an autogenerated file and should not be edited. -@@ -59,7 +57,7 @@ func main() { - versionStr := strings.TrimSpace(string(versionContent)) - - fmt.Printf("Agent Version: %v", versionStr) -- if err := ioutil.WriteFile(filepath.Join("VERSION"), []byte(versionStr), appconfig.ReadWriteAccess); err != nil { -+ if err := ioutil.WriteFile(filepath.Join("VERSION"), []byte(versionStr), 0600); err != nil { - log.Fatalf("Error writing to VERSION file. %v", err) - } - -@@ -108,7 +106,7 @@ func main() { - - releaseNoteOutFile := strings.Join(releaseNoteLines, "\n") - -- if err = ioutil.WriteFile(filepath.Join(releaseNotesFile), []byte(releaseNoteOutFile), appconfig.ReadWriteAccess); err != nil { -+ if err = ioutil.WriteFile(filepath.Join(releaseNotesFile), []byte(releaseNoteOutFile), 0600); err != nil { - log.Fatalf("Error writing to RELEASENOTES.md file. %v", err) - } - --- -2.30.0 - diff --git a/pkgs/applications/networking/cluster/ssm-agent/default.nix b/pkgs/applications/networking/cluster/ssm-agent/default.nix deleted file mode 100644 index f6afcd7d884..00000000000 --- a/pkgs/applications/networking/cluster/ssm-agent/default.nix +++ /dev/null @@ -1,157 +0,0 @@ -{ lib -, writeShellScriptBin -, buildGoModule -, makeWrapper -, fetchFromGitHub -, coreutils -, nettools -, util-linux -, stdenv -, dmidecode -, bashInteractive -, nix-update-script -, testers -, ssm-agent -, overrideEtc ? true -}: - -let - # Tests use lsb_release, so we mock it (the SSM agent used to not - # read from our /etc/os-release file, but now it does) because in - # reality, it won't (shouldn't) be used when active on a system with - # /etc/os-release. If it is, we fake the only two fields it cares about. - fake-lsb-release = writeShellScriptBin "lsb_release" '' - . /etc/os-release || true - - case "$1" in - -i) echo "''${NAME:-unknown}";; - -r) echo "''${VERSION:-unknown}";; - esac - ''; - - binaries = { - "core" = "amazon-ssm-agent"; - "agent" = "ssm-agent-worker"; - "cli-main" = "ssm-cli"; - "worker" = "ssm-document-worker"; - "logging" = "ssm-session-logger"; - "sessionworker" = "ssm-session-worker"; - }; -in -buildGoModule rec { - pname = "amazon-ssm-agent"; - version = "3.2.1630.0"; - - src = fetchFromGitHub { - owner = "aws"; - repo = "amazon-ssm-agent"; - rev = "refs/tags/${version}"; - hash = "sha256-0tN0rBfz2VZ4UkYLFDGg9218O9vyyRT2Lrppu9TETao="; - }; - - vendorHash = null; - - patches = [ - # Some tests use networking, so we skip them. - ./0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch - - # They used constants from another package that I couldn't figure - # out how to resolve, so hardcoded the constants. - ./0002-version-gen-don-t-use-unnecessary-constants.patch - ]; - - nativeBuildInputs = [ makeWrapper ]; - - # See the list https://github.com/aws/amazon-ssm-agent/blob/3.2.1630.0/makefile#L120-L138 - # The updater is not built because it cannot work on NixOS - subPackages = [ - "core" - "agent" - "agent/cli-main" - "agent/framework/processor/executer/outofproc/worker" - "agent/session/logging" - "agent/framework/processor/executer/outofproc/sessionworker" - ]; - - ldflags = [ "-s" "-w" ]; - - postPatch = '' - printf "#!/bin/sh\ntrue" > ./Tools/src/checkstyle.sh - - substituteInPlace agent/platform/platform_unix.go \ - --replace "/usr/bin/uname" "${coreutils}/bin/uname" \ - --replace '"/bin", "hostname"' '"${nettools}/bin/hostname"' \ - --replace '"lsb_release"' '"${fake-lsb-release}/bin/lsb_release"' - - substituteInPlace agent/session/shell/shell_unix.go \ - --replace '"script"' '"${util-linux}/bin/script"' - - substituteInPlace agent/rebooter/rebooter_unix.go \ - --replace "/sbin/shutdown" "shutdown" - - echo "${version}" > VERSION - '' + lib.optionalString overrideEtc '' - substituteInPlace agent/appconfig/constants_unix.go \ - --replace '"/etc/amazon/ssm/"' '"${placeholder "out"}/etc/amazon/ssm/"' - '' + lib.optionalString stdenv.isLinux '' - substituteInPlace agent/managedInstances/fingerprint/hardwareInfo_unix.go \ - --replace /usr/sbin/dmidecode ${dmidecode}/bin/dmidecode - ''; - - preBuild = '' - # Note: if this step fails, please patch the code to fix it! Please only skip - # tests if it is not feasible for the test to pass in a sandbox. - make quick-integtest - - make pre-release - make pre-build - ''; - - installPhase = '' - runHook preInstall - - declare -A map=(${builtins.concatStringsSep " " (lib.mapAttrsToList (name: value: "[\"${name}\"]=\"${value}\"") binaries)}) - - for key in ''${!map[@]}; do - install -D -m 0555 -T "$GOPATH/bin/''${key}" "$out/bin/''${map[''${key}]}" - done - - # These templates retain their `.template` extensions on installation. The - # amazon-ssm-agent.json.template is required as default configuration when an - # amazon-ssm-agent.json isn't present. Here, we retain the template to show - # we're using the default configuration. - - # seelog.xml isn't actually required to run, but it does ship as a template - # with debian packages, so it's here for reference. Future work in the nixos - # module could use this template and substitute a different log level. - - install -D -m 0444 -t $out/etc/amazon/ssm amazon-ssm-agent.json.template - install -D -m 0444 -T seelog_unix.xml $out/etc/amazon/ssm/seelog.xml.template - - runHook postInstall - ''; - - postFixup = '' - wrapProgram $out/bin/amazon-ssm-agent --prefix PATH : ${bashInteractive}/bin - ''; - - passthru = { - updateScript = nix-update-script { }; - tests.version = testers.testVersion { - package = ssm-agent; - command = "amazon-ssm-agent --version"; - }; - }; - - meta = with lib; { - description = "Agent to enable remote management of your Amazon EC2 instance configuration"; - changelog = "https://github.com/aws/amazon-ssm-agent/releases/tag/${version}"; - homepage = "https://github.com/aws/amazon-ssm-agent"; - license = licenses.asl20; - platforms = platforms.unix; - maintainers = with maintainers; [ copumpkin manveru anthonyroussel ]; - - # Darwin support is broken - broken = stdenv.isDarwin; - }; -} diff --git a/pkgs/by-name/am/amazon-ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch b/pkgs/by-name/am/amazon-ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch new file mode 100644 index 00000000000..364f7653efa --- /dev/null +++ b/pkgs/by-name/am/amazon-ssm-agent/0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch @@ -0,0 +1,44 @@ +From bea6307ec2a77d90d59c13940381d73ec0f05b70 Mon Sep 17 00:00:00 2001 +From: Graham Christensen +Date: Mon, 1 Mar 2021 10:57:44 -0500 +Subject: [PATCH] Disable NIC tests that fail in the Nix sandbox. + +--- + agent/managedInstances/fingerprint/fingerprint_integ_test.go | 2 ++ + agent/ssm/service_test.go | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/agent/managedInstances/fingerprint/fingerprint_integ_test.go b/agent/managedInstances/fingerprint/fingerprint_integ_test.go +index a1f969ff..631ea1f5 100644 +--- a/agent/managedInstances/fingerprint/fingerprint_integ_test.go ++++ b/agent/managedInstances/fingerprint/fingerprint_integ_test.go +@@ -28,12 +28,14 @@ func TestHostnameInfo(t *testing.T) { + } + + func TestPrimaryIpInfo(t *testing.T) { ++ t.Skip("The Nix build sandbox has no non-loopback IPs, causing this test to fail."); + ip, err := primaryIpInfo() + assert.NoError(t, err, "expected no error fetching the primary ip") + assert.NotEmpty(t, ip, "expected to fetch primary ip") + } + + func TestMacAddrInfo(t *testing.T) { ++ t.Skip("The Nix build sandbox has no non-loopback interfaces, causing this test to fail."); + mac, err := macAddrInfo() + assert.NoError(t, err, "expected no error fetching the mac addr") + assert.NotEmpty(t, mac, "expected to fetch mac address") +diff --git a/agent/ssm/service_test.go b/agent/ssm/service_test.go +index f4b34f83..d8216dba 100644 +--- a/agent/ssm/service_test.go ++++ b/agent/ssm/service_test.go +@@ -85,6 +85,7 @@ func (suite *SsmServiceTestSuite) TestUpdateEmptyInstanceInformation() { + // Test function for update instance information + // This function update the agent name, agent statuc, and agent version. + func (suite *SsmServiceTestSuite) TestUpdateInstanceInformation() { ++ suite.T().Skip("The Nix build sandbox has no interfaces for IP and MAC address reports."); + // Give mock value to test UpdateInstanceInformation, assert the error is nil, assert the log.Debug function get called. + response, err := suite.sdkService.UpdateInstanceInformation(suite.logMock, "2.2.3.2", "active", "Amazon-ssm-agent") + assert.Nil(suite.T(), err, "Err should be nil") +-- +2.29.2 + diff --git a/pkgs/by-name/am/amazon-ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch b/pkgs/by-name/am/amazon-ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch new file mode 100644 index 00000000000..234e510d3d1 --- /dev/null +++ b/pkgs/by-name/am/amazon-ssm-agent/0002-version-gen-don-t-use-unnecessary-constants.patch @@ -0,0 +1,46 @@ +From 473e3f8544915a35b3a45c548743978b34e5310e Mon Sep 17 00:00:00 2001 +From: Cole Helbling +Date: Tue, 2 Mar 2021 00:24:00 -0800 +Subject: [PATCH] version-gen: don't use unnecessary constants + +This prevents the tool from being built with Nix, because this project +doesn't use Go modules (or something; I'm not really familiar with Go, +much less Go + Nix). +--- + agent/version/versiongenerator/version-gen.go | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/agent/version/versiongenerator/version-gen.go b/agent/version/versiongenerator/version-gen.go +index d710effc..55c9a001 100644 +--- a/agent/version/versiongenerator/version-gen.go ++++ b/agent/version/versiongenerator/version-gen.go +@@ -22,8 +22,6 @@ import ( + "path/filepath" + "strings" + "text/template" +- +- "github.com/aws/amazon-ssm-agent/agent/appconfig" + ) + + const versiongoTemplate = `// This is an autogenerated file and should not be edited. +@@ -59,7 +57,7 @@ func main() { + versionStr := strings.TrimSpace(string(versionContent)) + + fmt.Printf("Agent Version: %v", versionStr) +- if err := ioutil.WriteFile(filepath.Join("VERSION"), []byte(versionStr), appconfig.ReadWriteAccess); err != nil { ++ if err := ioutil.WriteFile(filepath.Join("VERSION"), []byte(versionStr), 0600); err != nil { + log.Fatalf("Error writing to VERSION file. %v", err) + } + +@@ -108,7 +106,7 @@ func main() { + + releaseNoteOutFile := strings.Join(releaseNoteLines, "\n") + +- if err = ioutil.WriteFile(filepath.Join(releaseNotesFile), []byte(releaseNoteOutFile), appconfig.ReadWriteAccess); err != nil { ++ if err = ioutil.WriteFile(filepath.Join(releaseNotesFile), []byte(releaseNoteOutFile), 0600); err != nil { + log.Fatalf("Error writing to RELEASENOTES.md file. %v", err) + } + +-- +2.30.0 + diff --git a/pkgs/by-name/am/amazon-ssm-agent/package.nix b/pkgs/by-name/am/amazon-ssm-agent/package.nix new file mode 100644 index 00000000000..b884eb9ed06 --- /dev/null +++ b/pkgs/by-name/am/amazon-ssm-agent/package.nix @@ -0,0 +1,157 @@ +{ lib +, writeShellScriptBin +, buildGoModule +, makeWrapper +, fetchFromGitHub +, coreutils +, nettools +, util-linux +, stdenv +, dmidecode +, bashInteractive +, nix-update-script +, testers +, amazon-ssm-agent +, overrideEtc ? true +}: + +let + # Tests use lsb_release, so we mock it (the SSM agent used to not + # read from our /etc/os-release file, but now it does) because in + # reality, it won't (shouldn't) be used when active on a system with + # /etc/os-release. If it is, we fake the only two fields it cares about. + fake-lsb-release = writeShellScriptBin "lsb_release" '' + . /etc/os-release || true + + case "$1" in + -i) echo "''${NAME:-unknown}";; + -r) echo "''${VERSION:-unknown}";; + esac + ''; + + binaries = { + "core" = "amazon-ssm-agent"; + "agent" = "ssm-agent-worker"; + "cli-main" = "ssm-cli"; + "worker" = "ssm-document-worker"; + "logging" = "ssm-session-logger"; + "sessionworker" = "ssm-session-worker"; + }; +in +buildGoModule rec { + pname = "amazon-ssm-agent"; + version = "3.2.1630.0"; + + src = fetchFromGitHub { + owner = "aws"; + repo = "amazon-ssm-agent"; + rev = "refs/tags/${version}"; + hash = "sha256-0tN0rBfz2VZ4UkYLFDGg9218O9vyyRT2Lrppu9TETao="; + }; + + vendorHash = null; + + patches = [ + # Some tests use networking, so we skip them. + ./0001-Disable-NIC-tests-that-fail-in-the-Nix-sandbox.patch + + # They used constants from another package that I couldn't figure + # out how to resolve, so hardcoded the constants. + ./0002-version-gen-don-t-use-unnecessary-constants.patch + ]; + + nativeBuildInputs = [ makeWrapper ]; + + # See the list https://github.com/aws/amazon-ssm-agent/blob/3.2.1630.0/makefile#L120-L138 + # The updater is not built because it cannot work on NixOS + subPackages = [ + "core" + "agent" + "agent/cli-main" + "agent/framework/processor/executer/outofproc/worker" + "agent/session/logging" + "agent/framework/processor/executer/outofproc/sessionworker" + ]; + + ldflags = [ "-s" "-w" ]; + + postPatch = '' + printf "#!/bin/sh\ntrue" > ./Tools/src/checkstyle.sh + + substituteInPlace agent/platform/platform_unix.go \ + --replace "/usr/bin/uname" "${coreutils}/bin/uname" \ + --replace '"/bin", "hostname"' '"${nettools}/bin/hostname"' \ + --replace '"lsb_release"' '"${fake-lsb-release}/bin/lsb_release"' + + substituteInPlace agent/session/shell/shell_unix.go \ + --replace '"script"' '"${util-linux}/bin/script"' + + substituteInPlace agent/rebooter/rebooter_unix.go \ + --replace "/sbin/shutdown" "shutdown" + + echo "${version}" > VERSION + '' + lib.optionalString overrideEtc '' + substituteInPlace agent/appconfig/constants_unix.go \ + --replace '"/etc/amazon/ssm/"' '"${placeholder "out"}/etc/amazon/ssm/"' + '' + lib.optionalString stdenv.isLinux '' + substituteInPlace agent/managedInstances/fingerprint/hardwareInfo_unix.go \ + --replace /usr/sbin/dmidecode ${dmidecode}/bin/dmidecode + ''; + + preBuild = '' + # Note: if this step fails, please patch the code to fix it! Please only skip + # tests if it is not feasible for the test to pass in a sandbox. + make quick-integtest + + make pre-release + make pre-build + ''; + + installPhase = '' + runHook preInstall + + declare -A map=(${builtins.concatStringsSep " " (lib.mapAttrsToList (name: value: "[\"${name}\"]=\"${value}\"") binaries)}) + + for key in ''${!map[@]}; do + install -D -m 0555 -T "$GOPATH/bin/''${key}" "$out/bin/''${map[''${key}]}" + done + + # These templates retain their `.template` extensions on installation. The + # amazon-ssm-agent.json.template is required as default configuration when an + # amazon-ssm-agent.json isn't present. Here, we retain the template to show + # we're using the default configuration. + + # seelog.xml isn't actually required to run, but it does ship as a template + # with debian packages, so it's here for reference. Future work in the nixos + # module could use this template and substitute a different log level. + + install -D -m 0444 -t $out/etc/amazon/ssm amazon-ssm-agent.json.template + install -D -m 0444 -T seelog_unix.xml $out/etc/amazon/ssm/seelog.xml.template + + runHook postInstall + ''; + + postFixup = '' + wrapProgram $out/bin/amazon-ssm-agent --prefix PATH : ${bashInteractive}/bin + ''; + + passthru = { + updateScript = nix-update-script { }; + tests.version = testers.testVersion { + package = amazon-ssm-agent; + command = "amazon-ssm-agent --version"; + }; + }; + + meta = with lib; { + description = "Agent to enable remote management of your Amazon EC2 instance configuration"; + changelog = "https://github.com/aws/amazon-ssm-agent/releases/tag/${version}"; + homepage = "https://github.com/aws/amazon-ssm-agent"; + license = licenses.asl20; + platforms = platforms.unix; + maintainers = with maintainers; [ copumpkin manveru anthonyroussel ]; + + # Darwin support is broken + broken = stdenv.isDarwin; + }; +} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index c1d23ad8fba..3a6fe8700d3 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -849,6 +849,7 @@ mapAliases ({ spotify-unwrapped = spotify; # added 2022-11-06 spring-boot = spring-boot-cli; # added 2020-04-24 squid4 = throw "'squid4' has been renamed to/replaced by 'squid'"; # Converted to throw 2023-09-10 + ssm-agent = amazon-ssm-agent; # Added 2023-10-17 starboard-octant-plugin = throw "starboard-octant-plugin has been dropped due to needing octant which is archived"; # Added 2023-09-29 steam-run-native = steam-run; # added 2022-02-21 sumneko-lua-language-server = lua-language-server; # Added 2023-02-07 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 5a23e5416f9..6fd9e0d0740 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -18134,7 +18134,6 @@ with pkgs; inherit (darwin) libobjc; }; - ssm-agent = callPackage ../applications/networking/cluster/ssm-agent { }; ssm-session-manager-plugin = callPackage ../applications/networking/cluster/ssm-session-manager-plugin { }; starlark = callPackage ../development/interpreters/starlark { }; -- cgit 1.4.1 From cc6c2d32f297744e7ef7848fdf5b1886fa04ba4f Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Mon, 23 Oct 2023 19:29:30 +0200 Subject: rosenpass: refactor, add module and test (#254813) --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/networking/rosenpass.nix | 233 ++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/rosenpass.nix | 217 ++++++++++++++++++++ pkgs/tools/misc/envsubst/default.nix | 1 + pkgs/tools/networking/rosenpass/default.nix | 72 ++----- pkgs/tools/networking/rosenpass/tools.nix | 30 +++ pkgs/top-level/all-packages.nix | 2 + 9 files changed, 507 insertions(+), 52 deletions(-) create mode 100644 nixos/modules/services/networking/rosenpass.nix create mode 100644 nixos/tests/rosenpass.nix create mode 100644 pkgs/tools/networking/rosenpass/tools.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index be4ce3c27d8..bc2a1512427 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -121,6 +121,8 @@ - [Soft Serve](https://github.com/charmbracelet/soft-serve), a tasty, self-hostable Git server for the command line. Available as [services.soft-serve](#opt-services.soft-serve.enable). +- [Rosenpass](https://rosenpass.eu/), a service for post-quantum-secure VPNs with WireGuard. Available as [services.rosenpass](#opt-services.rosenpass.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - `network-online.target` has been fixed to no longer time out for systems with `networking.useDHCP = true` and `networking.useNetworkd = true`. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 47b262bf4d9..81b7b981a44 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1047,6 +1047,7 @@ ./services/networking/redsocks.nix ./services/networking/resilio.nix ./services/networking/robustirc-bridge.nix + ./services/networking/rosenpass.nix ./services/networking/routedns.nix ./services/networking/rpcbind.nix ./services/networking/rxe.nix diff --git a/nixos/modules/services/networking/rosenpass.nix b/nixos/modules/services/networking/rosenpass.nix new file mode 100644 index 00000000000..d2a264b83d6 --- /dev/null +++ b/nixos/modules/services/networking/rosenpass.nix @@ -0,0 +1,233 @@ +{ config +, lib +, options +, pkgs +, ... +}: +let + inherit (lib) + attrValues + concatLines + concatMap + filter + filterAttrsRecursive + flatten + getExe + mdDoc + mkIf + optional + ; + + cfg = config.services.rosenpass; + opt = options.services.rosenpass; + settingsFormat = pkgs.formats.toml { }; +in +{ + options.services.rosenpass = + let + inherit (lib) + literalExpression + mdDoc + mkOption + ; + inherit (lib.types) + enum + listOf + nullOr + path + str + submodule + ; + in + { + enable = lib.mkEnableOption (mdDoc "Rosenpass"); + + package = lib.mkPackageOption pkgs "rosenpass" { }; + + defaultDevice = mkOption { + type = nullOr str; + description = mdDoc "Name of the network interface to use for all peers by default."; + example = "wg0"; + }; + + settings = mkOption { + type = submodule { + freeformType = settingsFormat.type; + + options = { + public_key = mkOption { + type = path; + description = mdDoc "Path to a file containing the public key of the local Rosenpass peer. Generate this by running {command}`rosenpass gen-keys`."; + }; + + secret_key = mkOption { + type = path; + description = mdDoc "Path to a file containing the secret key of the local Rosenpass peer. Generate this by running {command}`rosenpass gen-keys`."; + }; + + listen = mkOption { + type = listOf str; + description = mdDoc "List of local endpoints to listen for connections."; + default = [ ]; + example = literalExpression "[ \"0.0.0.0:10000\" ]"; + }; + + verbosity = mkOption { + type = enum [ "Verbose" "Quiet" ]; + default = "Quiet"; + description = mdDoc "Verbosity of output produced by the service."; + }; + + peers = + let + peer = submodule { + freeformType = settingsFormat.type; + + options = { + public_key = mkOption { + type = path; + description = mdDoc "Path to a file containing the public key of the remote Rosenpass peer."; + }; + + endpoint = mkOption { + type = nullOr str; + default = null; + description = mdDoc "Endpoint of the remote Rosenpass peer."; + }; + + device = mkOption { + type = str; + default = cfg.defaultDevice; + defaultText = literalExpression "config.${opt.defaultDevice}"; + description = mdDoc "Name of the local WireGuard interface to use for this peer."; + }; + + peer = mkOption { + type = str; + description = mdDoc "WireGuard public key corresponding to the remote Rosenpass peer."; + }; + }; + }; + in + mkOption { + type = listOf peer; + description = mdDoc "List of peers to exchange keys with."; + default = [ ]; + }; + }; + }; + default = { }; + description = mdDoc "Configuration for Rosenpass, see for further information."; + }; + }; + + config = mkIf cfg.enable { + warnings = + let + # NOTE: In the descriptions below, we tried to refer to e.g. + # options.systemd.network.netdevs."".wireguardPeers.*.PublicKey + # directly, but don't know how to traverse "" and * in this path. + extractions = [ + { + relevant = config.systemd.network.enable; + root = config.systemd.network.netdevs; + peer = (x: x.wireguardPeers); + key = (x: if x.wireguardPeerConfig ? PublicKey then x.wireguardPeerConfig.PublicKey else null); + description = mdDoc "${options.systemd.network.netdevs}.\"\".wireguardPeers.*.wireguardPeerConfig.PublicKey"; + } + { + relevant = config.networking.wireguard.enable; + root = config.networking.wireguard.interfaces; + peer = (x: x.peers); + key = (x: x.publicKey); + description = mdDoc "${options.networking.wireguard.interfaces}.\"\".peers.*.publicKey"; + } + rec { + relevant = root != { }; + root = config.networking.wg-quick.interfaces; + peer = (x: x.peers); + key = (x: x.publicKey); + description = mdDoc "${options.networking.wg-quick.interfaces}.\"\".peers.*.publicKey"; + } + ]; + relevantExtractions = filter (x: x.relevant) extractions; + extract = { root, peer, key, ... }: + filter (x: x != null) (flatten (concatMap (x: (map key (peer x))) (attrValues root))); + configuredKeys = flatten (map extract relevantExtractions); + itemize = xs: concatLines (map (x: " - ${x}") xs); + descriptions = map (x: "`${x.description}`"); + missingKeys = filter (key: !builtins.elem key configuredKeys) (map (x: x.peer) cfg.settings.peers); + unusual = '' + While this may work as expected, e.g. you want to manually configure WireGuard, + such a scenario is unusual. Please double-check your configuration. + ''; + in + (optional (relevantExtractions != [ ] && missingKeys != [ ]) '' + You have configured Rosenpass peers with the WireGuard public keys: + ${itemize missingKeys} + But there is no corresponding active Wireguard peer configuration in any of: + ${itemize (descriptions relevantExtractions)} + ${unusual} + '') + ++ + optional (relevantExtractions == [ ]) '' + You have configured Rosenpass, but you have not configured Wireguard via any of: + ${itemize (descriptions extractions)} + ${unusual} + ''; + + environment.systemPackages = [ cfg.package pkgs.wireguard-tools ]; + + systemd.services.rosenpass = + let + filterNonNull = filterAttrsRecursive (_: v: v != null); + config = settingsFormat.generate "config.toml" ( + filterNonNull (cfg.settings + // + ( + let + credentialPath = id: "$CREDENTIALS_DIRECTORY/${id}"; + # NOTE: We would like to remove all `null` values inside `cfg.settings` + # recursively, since `settingsFormat.generate` cannot handle `null`. + # This would require to traverse both attribute sets and lists recursively. + # `filterAttrsRecursive` only recurses into attribute sets, but not + # into values that might contain other attribute sets (such as lists, + # e.g. `cfg.settings.peers`). Here, we just specialize on `cfg.settings.peers`, + # and this may break unexpectedly whenever a `null` value is contained + # in a list in `cfg.settings`, other than `cfg.settings.peers`. + peersWithoutNulls = map filterNonNull cfg.settings.peers; + in + { + secret_key = credentialPath "pqsk"; + public_key = credentialPath "pqpk"; + peers = peersWithoutNulls; + } + ) + ) + ); + in + rec { + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + path = [ cfg.package pkgs.wireguard-tools ]; + + serviceConfig = { + User = "rosenpass"; + Group = "rosenpass"; + RuntimeDirectory = "rosenpass"; + DynamicUser = true; + AmbientCapabilities = [ "CAP_NET_ADMIN" ]; + LoadCredential = [ + "pqsk:${cfg.settings.secret_key}" + "pqpk:${cfg.settings.public_key}" + ]; + }; + + # See + environment.CONFIG = "%t/${serviceConfig.RuntimeDirectory}/config.toml"; + + preStart = "${getExe pkgs.envsubst} -i ${config} -o \"$CONFIG\""; + script = "rosenpass exchange-config \"$CONFIG\""; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 42d620b512c..d9d58bbd66a 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -703,6 +703,7 @@ in { rkvm = handleTest ./rkvm {}; robustirc-bridge = handleTest ./robustirc-bridge.nix {}; roundcube = handleTest ./roundcube.nix {}; + rosenpass = handleTest ./rosenpass.nix {}; rshim = handleTest ./rshim.nix {}; rspamd = handleTest ./rspamd.nix {}; rss2email = handleTest ./rss2email.nix {}; diff --git a/nixos/tests/rosenpass.nix b/nixos/tests/rosenpass.nix new file mode 100644 index 00000000000..ec4046c8c03 --- /dev/null +++ b/nixos/tests/rosenpass.nix @@ -0,0 +1,217 @@ +import ./make-test-python.nix ({ pkgs, ... }: +let + deviceName = "rp0"; + + server = { + ip = "fe80::1"; + wg = { + public = "mQufmDFeQQuU/fIaB2hHgluhjjm1ypK4hJr1cW3WqAw="; + secret = "4N5Y1dldqrpsbaEiY8O0XBUGUFf8vkvtBtm8AoOX7Eo="; + listen = 10000; + }; + }; + client = { + ip = "fe80::2"; + wg = { + public = "Mb3GOlT7oS+F3JntVKiaD7SpHxLxNdtEmWz/9FMnRFU="; + secret = "uC5dfGMv7Oxf5UDfdPkj6rZiRZT2dRWp5x8IQxrNcUE="; + }; + }; +in +{ + name = "rosenpass"; + + nodes = + let + shared = peer: { config, modulesPath, ... }: { + imports = [ "${modulesPath}/services/networking/rosenpass.nix" ]; + + boot.kernelModules = [ "wireguard" ]; + + services.rosenpass = { + enable = true; + defaultDevice = deviceName; + settings = { + verbosity = "Verbose"; + public_key = "/etc/rosenpass/pqpk"; + secret_key = "/etc/rosenpass/pqsk"; + }; + }; + + networking.firewall.allowedUDPPorts = [ 9999 ]; + + systemd.network = { + enable = true; + networks."rosenpass" = { + matchConfig.Name = deviceName; + networkConfig.IPForward = true; + address = [ "${peer.ip}/64" ]; + }; + + netdevs."10-rp0" = { + netdevConfig = { + Kind = "wireguard"; + Name = deviceName; + }; + wireguardConfig.PrivateKeyFile = "/etc/wireguard/wgsk"; + }; + }; + + environment.etc."wireguard/wgsk" = { + text = peer.wg.secret; + user = "systemd-network"; + group = "systemd-network"; + }; + }; + in + { + server = { + imports = [ (shared server) ]; + + networking.firewall.allowedUDPPorts = [ server.wg.listen ]; + + systemd.network.netdevs."10-${deviceName}" = { + wireguardConfig.ListenPort = server.wg.listen; + wireguardPeers = [ + { + wireguardPeerConfig = { + AllowedIPs = [ "::/0" ]; + PublicKey = client.wg.public; + }; + } + ]; + }; + + services.rosenpass.settings = { + listen = [ "0.0.0.0:9999" ]; + peers = [ + { + public_key = "/etc/rosenpass/peers/client/pqpk"; + peer = client.wg.public; + } + ]; + }; + }; + client = { + imports = [ (shared client) ]; + + systemd.network.netdevs."10-${deviceName}".wireguardPeers = [ + { + wireguardPeerConfig = { + AllowedIPs = [ "::/0" ]; + PublicKey = server.wg.public; + Endpoint = "server:${builtins.toString server.wg.listen}"; + }; + } + ]; + + services.rosenpass.settings.peers = [ + { + public_key = "/etc/rosenpass/peers/server/pqpk"; + endpoint = "server:9999"; + peer = server.wg.public; + } + ]; + }; + }; + + testScript = { ... }: '' + from os import system + + # Full path to rosenpass in the store, to avoid fiddling with `$PATH`. + rosenpass = "${pkgs.rosenpass}/bin/rosenpass" + + # Path in `/etc` where keys will be placed. + etc = "/etc/rosenpass" + + start_all() + + for machine in [server, client]: + machine.wait_for_unit("multi-user.target") + + # Gently stop Rosenpass to avoid crashes during key generation/distribution. + for machine in [server, client]: + machine.execute("systemctl stop rosenpass.service") + + for (name, machine, remote) in [("server", server, client), ("client", client, server)]: + pk, sk = f"{name}.pqpk", f"{name}.pqsk" + system(f"{rosenpass} gen-keys --force --secret-key {sk} --public-key {pk}") + machine.copy_from_host(sk, f"{etc}/pqsk") + machine.copy_from_host(pk, f"{etc}/pqpk") + remote.copy_from_host(pk, f"{etc}/peers/{name}/pqpk") + + for machine in [server, client]: + machine.execute("systemctl start rosenpass.service") + + for machine in [server, client]: + machine.wait_for_unit("rosenpass.service") + + with subtest("ping"): + client.succeed("ping -c 2 -i 0.5 ${server.ip}%${deviceName}") + + with subtest("preshared-keys"): + # Rosenpass works by setting the WireGuard preshared key at regular intervals. + # Thus, if it is not active, then no key will be set, and the output of `wg show` will contain "none". + # Otherwise, if it is active, then the key will be set and "none" will not be found in the output of `wg show`. + for machine in [server, client]: + machine.wait_until_succeeds("wg show all preshared-keys | grep --invert-match none", timeout=5) + ''; + + # NOTE: Below configuration is for "interactive" (=developing/debugging) only. + interactive.nodes = + let + inherit (import ./ssh-keys.nix pkgs) snakeOilPublicKey snakeOilPrivateKey; + + sshAndKeyGeneration = { + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; + environment.systemPackages = [ + (pkgs.writeShellApplication { + name = "gen-keys"; + runtimeInputs = [ pkgs.rosenpass ]; + text = '' + HOST="$(hostname)" + if [ "$HOST" == "server" ] + then + PEER="client" + else + PEER="server" + fi + + # Generate keypair. + mkdir -vp /etc/rosenpass/peers/$PEER + rosenpass gen-keys --force --secret-key /etc/rosenpass/pqsk --public-key /etc/rosenpass/pqpk + + # Set up SSH key. + mkdir -p /root/.ssh + cp ${snakeOilPrivateKey} /root/.ssh/id_ecdsa + chmod 0400 /root/.ssh/id_ecdsa + + # Copy public key to other peer. + # shellcheck disable=SC2029 + ssh -o StrictHostKeyChecking=no $PEER "mkdir -pv /etc/rosenpass/peers/$HOST" + scp /etc/rosenpass/pqpk "$PEER:/etc/rosenpass/peers/$HOST/pqpk" + ''; + }) + ]; + }; + + # Use kmscon + # to provide a slightly nicer console, and while we're at it, + # also use a nice font. + # With kmscon, we can for example zoom in/out using [Ctrl] + [+] + # and [Ctrl] + [-] + niceConsoleAndAutologin.services.kmscon = { + enable = true; + autologinUser = "root"; + fonts = [{ + name = "Fira Code"; + package = pkgs.fira-code; + }]; + }; + in + { + server = sshAndKeyGeneration // niceConsoleAndAutologin; + client = sshAndKeyGeneration // niceConsoleAndAutologin; + }; +}) diff --git a/pkgs/tools/misc/envsubst/default.nix b/pkgs/tools/misc/envsubst/default.nix index b3a1be04d92..8cd59df31b1 100644 --- a/pkgs/tools/misc/envsubst/default.nix +++ b/pkgs/tools/misc/envsubst/default.nix @@ -22,5 +22,6 @@ buildGoModule rec { homepage = "https://github.com/a8m/envsubst"; license = licenses.mit; maintainers = with maintainers; [ nicknovitski ]; + mainProgram = "envsubst"; }; } diff --git a/pkgs/tools/networking/rosenpass/default.nix b/pkgs/tools/networking/rosenpass/default.nix index 07669cfeb01..9467904fe69 100644 --- a/pkgs/tools/networking/rosenpass/default.nix +++ b/pkgs/tools/networking/rosenpass/default.nix @@ -1,85 +1,53 @@ { lib -, targetPlatform , fetchFromGitHub +, nixosTests , rustPlatform +, targetPlatform +, installShellFiles , cmake -, makeWrapper -, pkg-config -, removeReferencesTo -, coreutils -, findutils -, gawk -, wireguard-tools -, bash , libsodium +, pkg-config }: - -let - rpBinPath = lib.makeBinPath [ - coreutils - findutils - gawk - wireguard-tools - ]; -in rustPlatform.buildRustPackage rec { pname = "rosenpass"; - version = "0.2.0"; + version = "unstable-2023-09-28"; + src = fetchFromGitHub { owner = pname; repo = pname; - rev = "v${version}"; - sha256 = "sha256-r7/3C5DzXP+9w4rp9XwbP+/NK1axIP6s3Iiio1xRMbk="; + rev = "b15f17133f8b5c3c5175b4cfd4fc10039a4e203f"; + hash = "sha256-UXAkmt4VY0irLK2k4t6SW+SEodFE3CbX5cFbsPG0ZCo="; }; - cargoHash = "sha256-g2w3lZXQ3Kg3ydKdFs8P2lOPfIkfTbAF0MhxsJoX/E4="; + cargoHash = "sha256-N1DQHkgKgkDQ6DbgQJlpZkZ7AMTqX3P8R/cWr14jK2I="; nativeBuildInputs = [ cmake # for oqs build in the oqs-sys crate - makeWrapper # for the rp shellscript - pkg-config # let libsodium-sys-stable find libsodium - removeReferencesTo + pkg-config rustPlatform.bindgenHook # for C-bindings in the crypto libs + installShellFiles ]; - buildInputs = [ - bash # for patchShebangs to find it - libsodium - ]; - - # otherwise pkg-config tries to link non-existent dynamic libs during the build of liboqs - PKG_CONFIG_ALL_STATIC = true; - - # liboqs requires quite a lot of stack memory, thus we adjust the default stack size picked for - # new threads (which is used by `cargo test`) to be _big enough_ - RUST_MIN_STACK = 8 * 1024 * 1024; # 8 MiB + buildInputs = [ libsodium ]; # nix defaults to building for aarch64 _without_ the armv8-a # crypto extensions, but liboqs depends on these - preBuild = lib.optionalString targetPlatform.isAarch - ''NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"''; - - preInstall = '' - install -D rp $out/bin/rp - wrapProgram $out/bin/rp --prefix PATH : "${ rpBinPath }" - for file in doc/*.1 - do - install -D $file $out/share/man/man1/''${file##*/} - done + preBuild = lib.optionalString targetPlatform.isAarch64 '' + NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto" ''; - # nix propagates the *.dev outputs of buildInputs for static builds, but that is non-sense for an - # executables only package - postFixup = '' - find -type f -exec remove-references-to -t ${bash.dev} \ - -t ${libsodium.dev} {} \; + postInstall = '' + installManPage doc/rosenpass.1 ''; + passthru.tests.rosenpass = nixosTests.rosenpass; + meta = with lib; { description = "Build post-quantum-secure VPNs with WireGuard!"; homepage = "https://rosenpass.eu/"; license = with licenses; [ mit /* or */ asl20 ]; maintainers = with maintainers; [ wucke13 ]; - platforms = platforms.all; + platforms = [ "aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux" ]; + mainProgram = "rosenpass"; }; } diff --git a/pkgs/tools/networking/rosenpass/tools.nix b/pkgs/tools/networking/rosenpass/tools.nix new file mode 100644 index 00000000000..fb59436b381 --- /dev/null +++ b/pkgs/tools/networking/rosenpass/tools.nix @@ -0,0 +1,30 @@ +{ lib +, stdenv +, makeWrapper +, installShellFiles +, coreutils +, findutils +, gawk +, rosenpass +, wireguard-tools +}: +stdenv.mkDerivation { + inherit (rosenpass) version src; + pname = "rosenpass-tools"; + + nativeBuildInputs = [ makeWrapper installShellFiles ]; + + postInstall = '' + install -D $src/rp $out/bin/rp + installManPage $src/doc/rp.1 + wrapProgram $out/bin/rp \ + --prefix PATH : ${lib.makeBinPath [ + coreutils findutils gawk rosenpass wireguard-tools + ]} + ''; + + meta = rosenpass.meta // { + description = "This package contains the Rosenpass tool `rp`, which is a script that wraps the `rosenpass` binary."; + mainProgram = "rp"; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c3ad477f742..bdcbe115f01 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -12827,6 +12827,8 @@ with pkgs; rosenpass = callPackage ../tools/networking/rosenpass { }; + rosenpass-tools = callPackage ../tools/networking/rosenpass/tools.nix { }; + rot8 = callPackage ../tools/misc/rot8 { }; rowhammer-test = callPackage ../tools/system/rowhammer-test { }; -- cgit 1.4.1 From bf5f01ee527fd7ca512741da0d920b5696309448 Mon Sep 17 00:00:00 2001 From: Yureka Date: Wed, 10 May 2023 14:28:38 +0200 Subject: nixos/fastnetmon-advanced: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + .../services/networking/fastnetmon-advanced.nix | 222 +++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 nixos/modules/services/networking/fastnetmon-advanced.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index be4ce3c27d8..d3ff83afddb 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -107,6 +107,8 @@ - [NNCP](http://www.nncpgo.org/). Added nncp-daemon and nncp-caller services. Configuration is set with [programs.nncp.settings](#opt-programs.nncp.settings) and the daemons are enabled at [services.nncp](#opt-services.nncp.caller.enable). +- [FastNetMon Advanced](https://fastnetmon.com/product-overview/), a commercial high performance DDoS detector / sensor. Available as [services.fastnetmon-advanced](#opt-services.fastnetmon-advanced.enable). + - [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers. - [audiobookshelf](https://github.com/advplyr/audiobookshelf/), a self-hosted audiobook and podcast server. Available as [services.audiobookshelf](#opt-services.audiobookshelf.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 47b262bf4d9..be5ae17e13e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -907,6 +907,7 @@ ./services/networking/eternal-terminal.nix ./services/networking/expressvpn.nix ./services/networking/fakeroute.nix + ./services/networking/fastnetmon-advanced.nix ./services/networking/ferm.nix ./services/networking/firefox-syncserver.nix ./services/networking/fireqos.nix diff --git a/nixos/modules/services/networking/fastnetmon-advanced.nix b/nixos/modules/services/networking/fastnetmon-advanced.nix new file mode 100644 index 00000000000..26e8ad8b76d --- /dev/null +++ b/nixos/modules/services/networking/fastnetmon-advanced.nix @@ -0,0 +1,222 @@ +{ config, lib, pkgs, ... }: + +let + # Background information: FastNetMon requires a MongoDB to start. This is because + # it uses MongoDB to store its configuration. That is, in a normal setup there is + # one collection with one document. + # To provide declarative configuration in our NixOS module, this database is + # completely emptied and replaced on each boot by the fastnetmon-setup service + # using the configuration backup functionality. + + cfg = config.services.fastnetmon-advanced; + settingsFormat = pkgs.formats.yaml { }; + + # obtain the default configs by starting up ferretdb and fcli in a derivation + default_configs = pkgs.runCommand "default-configs" { + nativeBuildInputs = [ + pkgs.ferretdb + pkgs.fastnetmon-advanced # for fcli + pkgs.proot + ]; + } '' + mkdir ferretdb fastnetmon $out + FERRETDB_TELEMETRY="disable" FERRETDB_HANDLER="sqlite" FERRETDB_STATE_DIR="$PWD/ferretdb" FERRETDB_SQLITE_URL="file:$PWD/ferretdb/" ferretdb & + + cat << EOF > fastnetmon/fastnetmon.conf + ${builtins.toJSON { + mongodb_username = ""; + }} + EOF + proot -b fastnetmon:/etc/fastnetmon -0 fcli create_configuration + proot -b fastnetmon:/etc/fastnetmon -0 fcli set bgp default + proot -b fastnetmon:/etc/fastnetmon -0 fcli export_configuration backup.tar + tar -C $out --no-same-owner -xvf backup.tar + ''; + + # merge the user configs into the default configs + config_tar = pkgs.runCommand "fastnetmon-config.tar" { + nativeBuildInputs = with pkgs; [ jq ]; + } '' + jq -s add ${default_configs}/main.json ${pkgs.writeText "main-add.json" (builtins.toJSON cfg.settings)} > main.json + mkdir hostgroup + ${lib.concatImapStringsSep "\n" (pos: hostgroup: '' + jq -s add ${default_configs}/hostgroup/0.json ${pkgs.writeText "hostgroup-${toString (pos - 1)}-add.json" (builtins.toJSON hostgroup)} > hostgroup/${toString (pos - 1)}.json + '') hostgroups} + mkdir bgp + ${lib.concatImapStringsSep "\n" (pos: bgp: '' + jq -s add ${default_configs}/bgp/0.json ${pkgs.writeText "bgp-${toString (pos - 1)}-add.json" (builtins.toJSON bgp)} > bgp/${toString (pos - 1)}.json + '') bgpPeers} + tar -cf $out main.json ${lib.concatImapStringsSep " " (pos: _: "hostgroup/${toString (pos - 1)}.json") hostgroups} ${lib.concatImapStringsSep " " (pos: _: "bgp/${toString (pos - 1)}.json") bgpPeers} + ''; + + hostgroups = lib.mapAttrsToList (name: hostgroup: { inherit name; } // hostgroup) cfg.hostgroups; + bgpPeers = lib.mapAttrsToList (name: bgpPeer: { inherit name; } // bgpPeer) cfg.bgpPeers; + +in { + options.services.fastnetmon-advanced = with lib; { + enable = mkEnableOption "the fastnetmon-advanced DDoS Protection daemon"; + + settings = mkOption { + description = '' + Extra configuration options to declaratively load into FastNetMon Advanced. + + See the [FastNetMon Advanced Configuration options reference](https://fastnetmon.com/docs-fnm-advanced/fastnetmon-advanced-configuration-options/) for more details. + ''; + type = settingsFormat.type; + default = {}; + example = literalExpression '' + { + networks_list = [ "192.0.2.0/24" ]; + gobgp = true; + gobgp_flow_spec_announces = true; + } + ''; + }; + hostgroups = mkOption { + description = "Hostgroups to declaratively load into FastNetMon Advanced"; + type = types.attrsOf settingsFormat.type; + default = {}; + }; + bgpPeers = mkOption { + description = "BGP Peers to declaratively load into FastNetMon Advanced"; + type = types.attrsOf settingsFormat.type; + default = {}; + }; + + enableAdvancedTrafficPersistence = mkOption { + description = "Store historical flow data in clickhouse"; + type = types.bool; + default = false; + }; + + traffic_db.settings = mkOption { + type = settingsFormat.type; + description = "Additional settings for /etc/fastnetmon/traffic_db.conf"; + }; + }; + + config = lib.mkMerge [ (lib.mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + fastnetmon-advanced # for fcli + ]; + + environment.etc."fastnetmon/license.lic".source = "/var/lib/fastnetmon/license.lic"; + environment.etc."fastnetmon/gobgpd.conf".source = "/run/fastnetmon/gobgpd.conf"; + environment.etc."fastnetmon/fastnetmon.conf".source = pkgs.writeText "fastnetmon.conf" (builtins.toJSON { + mongodb_username = ""; + }); + + services.ferretdb.enable = true; + + systemd.services.fastnetmon-setup = { + wantedBy = [ "multi-user.target" ]; + after = [ "ferretdb.service" ]; + path = with pkgs; [ fastnetmon-advanced config.systemd.package ]; + script = '' + fcli create_configuration + fcli delete hostgroup global + fcli import_configuration ${config_tar} + systemctl --no-block try-restart fastnetmon + ''; + serviceConfig.Type = "oneshot"; + }; + + systemd.services.fastnetmon = { + wantedBy = [ "multi-user.target" ]; + after = [ "ferretdb.service" "fastnetmon-setup.service" "polkit.service" ]; + path = with pkgs; [ iproute2 ]; + unitConfig = { + # Disable logic which shuts service when we do too many restarts + # We do restarts from sudo fcli commit and it's expected that we may have many restarts + # Details: https://github.com/systemd/systemd/issues/2416 + StartLimitInterval = 0; + }; + serviceConfig = { + ExecStart = "${pkgs.fastnetmon-advanced}/bin/fastnetmon --log_to_console"; + + LimitNOFILE = 65535; + # Restart service when it fails due to any reasons, we need to keep processing traffic no matter what happened + Restart= "on-failure"; + RestartSec= "5s"; + + DynamicUser = true; + CacheDirectory = "fastnetmon"; + RuntimeDirectory = "fastnetmon"; # for gobgpd config + StateDirectory = "fastnetmon"; # for license file + }; + }; + + security.polkit.enable = true; + security.polkit.extraConfig = '' + polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.systemd1.manage-units" && + subject.isInGroup("fastnetmon")) { + if (action.lookup("unit") == "gobgp.service") { + var verb = action.lookup("verb"); + if (verb == "start" || verb == "stop" || verb == "restart") { + return polkit.Result.YES; + } + } + } + }); + ''; + + # We don't use the existing gobgp NixOS module and package, because the gobgp + # version might not be compatible with fastnetmon. Also, the service name + # _must_ be 'gobgp' and not 'gobgpd', so that fastnetmon can reload the config. + systemd.services.gobgp = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "GoBGP Routing Daemon"; + unitConfig = { + ConditionPathExists = "/run/fastnetmon/gobgpd.conf"; + }; + serviceConfig = { + Type = "notify"; + ExecStartPre = "${pkgs.fastnetmon-advanced}/bin/fnm-gobgpd -f /run/fastnetmon/gobgpd.conf -d"; + SupplementaryGroups = [ "fastnetmon" ]; + ExecStart = "${pkgs.fastnetmon-advanced}/bin/fnm-gobgpd -f /run/fastnetmon/gobgpd.conf --sdnotify"; + ExecReload = "${pkgs.fastnetmon-advanced}/bin/fnm-gobgpd -r"; + DynamicUser = true; + AmbientCapabilities = "cap_net_bind_service"; + }; + }; + }) + + (lib.mkIf (cfg.enable && cfg.enableAdvancedTrafficPersistence) { + ## Advanced Traffic persistence + ## https://fastnetmon.com/docs-fnm-advanced/fastnetmon-advanced-traffic-persistency/ + + services.clickhouse.enable = true; + + services.fastnetmon-advanced.settings.traffic_db = true; + + services.fastnetmon-advanced.traffic_db.settings = { + clickhouse_batch_size = lib.mkDefault 1000; + clickhouse_batch_delay = lib.mkDefault 1; + traffic_db_host = lib.mkDefault "127.0.0.1"; + traffic_db_port = lib.mkDefault 8100; + clickhouse_host = lib.mkDefault "127.0.0.1"; + clickhouse_port = lib.mkDefault 9000; + clickhouse_user = lib.mkDefault "default"; + clickhouse_password = lib.mkDefault ""; + }; + environment.etc."fastnetmon/traffic_db.conf".text = builtins.toJSON cfg.traffic_db.settings; + + systemd.services.traffic_db = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = "${pkgs.fastnetmon-advanced}/bin/traffic_db"; + # Restart service when it fails due to any reasons, we need to keep processing traffic no matter what happened + Restart= "on-failure"; + RestartSec= "5s"; + + DynamicUser = true; + }; + }; + + }) ]; + + meta.maintainers = lib.teams.wdz.members; +} -- cgit 1.4.1 From 8e18ff0c2418df507eff96f4b199ea6002485f2f Mon Sep 17 00:00:00 2001 From: TomaSajt <62384384+TomaSajt@users.noreply.github.com> Date: Sun, 17 Sep 2023 17:12:55 +0200 Subject: nixos/lanraragi: init --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/lanraragi.nix | 100 ++++++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/lanraragi.nix | 40 +++++++++++ 4 files changed, 142 insertions(+) create mode 100644 nixos/modules/services/web-apps/lanraragi.nix create mode 100644 nixos/tests/lanraragi.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 47b262bf4d9..d975cc0507e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1268,6 +1268,7 @@ ./services/web-apps/kavita.nix ./services/web-apps/keycloak.nix ./services/web-apps/komga.nix + ./services/web-apps/lanraragi.nix ./services/web-apps/lemmy.nix ./services/web-apps/limesurvey.nix ./services/web-apps/mainsail.nix diff --git a/nixos/modules/services/web-apps/lanraragi.nix b/nixos/modules/services/web-apps/lanraragi.nix new file mode 100644 index 00000000000..f1ab8b8b4eb --- /dev/null +++ b/nixos/modules/services/web-apps/lanraragi.nix @@ -0,0 +1,100 @@ +{ pkgs, lib, config, ... }: + +let + cfg = config.services.lanraragi; +in +{ + meta.maintainers = with lib.maintainers; [ tomasajt ]; + + options.services = { + lanraragi = { + enable = lib.mkEnableOption (lib.mdDoc "LANraragi"); + package = lib.mkPackageOptionMD pkgs "lanraragi" { }; + + port = lib.mkOption { + type = lib.types.port; + default = 3000; + description = lib.mdDoc "Port for LANraragi's web interface."; + }; + + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/keys/lanraragi-password"; + description = lib.mdDoc '' + A file containing the password for LANraragi's admin interface. + ''; + }; + + redis = { + port = lib.mkOption { + type = lib.types.port; + default = 6379; + description = lib.mdDoc "Port for LANraragi's Redis server."; + }; + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/keys/redis-lanraragi-password"; + description = lib.mdDoc '' + A file containing the password for LANraragi's Redis server. + ''; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + services.redis.servers.lanraragi = { + enable = true; + port = cfg.redis.port; + requirePassFile = cfg.redis.passwordFile; + }; + + systemd.services.lanraragi = { + description = "LANraragi main service"; + after = [ "network.target" "redis-lanraragi.service" ]; + requires = [ "redis-lanraragi.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = lib.getExe cfg.package; + DynamicUser = true; + StateDirectory = "lanraragi"; + RuntimeDirectory = "lanraragi"; + LogsDirectory = "lanraragi"; + Restart = "on-failure"; + WorkingDirectory = "/var/lib/lanraragi"; + }; + environment = { + "LRR_TEMP_DIRECTORY" = "/run/lanraragi"; + "LRR_LOG_DIRECTORY" = "/var/log/lanraragi"; + "LRR_NETWORK" = "http://*:${toString cfg.port}"; + "HOME" = "/var/lib/lanraragi"; + }; + preStart = '' + REDIS_PASS=${lib.optionalString (cfg.redis.passwordFile != null) "$(head -n1 ${cfg.redis.passwordFile})"} + cat > lrr.conf < "127.0.0.1:${toString cfg.redis.port}", + redis_password => "$REDIS_PASS", + redis_database => "0", + redis_database_minion => "1", + redis_database_config => "2", + redis_database_search => "3", + } + EOF + '' + lib.optionalString (cfg.passwordFile != null) '' + PASS_HASH=$( + PASS=$(head -n1 ${cfg.passwordFile}) ${cfg.package.perlEnv}/bin/perl -I${cfg.package}/share/lanraragi/lib -e \ + 'use LANraragi::Controller::Config; print LANraragi::Controller::Config::make_password_hash($ENV{PASS})' \ + 2>/dev/null + ) + + ${lib.getExe pkgs.redis} -h 127.0.0.1 -p ${toString cfg.redis.port} -a "$REDIS_PASS" < Date: Fri, 20 Oct 2023 22:26:04 -0300 Subject: nixos/cardboard: init Copy-inspired from river. --- nixos/modules/module-list.nix | 1 + nixos/modules/programs/wayland/cardboard.nix | 31 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 nixos/modules/programs/wayland/cardboard.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ebca1ef62a5..bf24ee7603f 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -268,6 +268,7 @@ ./programs/usbtop.nix ./programs/vim.nix ./programs/wavemon.nix + ./programs/wayland/cardboard.nix ./programs/wayland/river.nix ./programs/wayland/sway.nix ./programs/wayland/waybar.nix diff --git a/nixos/modules/programs/wayland/cardboard.nix b/nixos/modules/programs/wayland/cardboard.nix new file mode 100644 index 00000000000..420efc69ebe --- /dev/null +++ b/nixos/modules/programs/wayland/cardboard.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.cardboard; +in +{ + meta.maintainers = with lib.maintainers; [ AndersonTorres ]; + + options.programs.cardboard = { + enable = lib.mkEnableOption (lib.mdDoc "cardboard"); + + package = lib.mkOption { + type = with lib.types; nullOr package; + default = pkgs.cardboard; + defaultText = lib.literalExpression "pkgs.cardboard"; + description = lib.mdDoc '' + cardboard package to use. + ''; + }; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + environment.systemPackages = [ cfg.package ]; + + # To make a cardboard session available for certain DMs like SDDM + services.xserver.displayManager.sessionPackages = [ cfg.package ]; + } + (import ./wayland-session.nix { inherit lib pkgs; }) + ]); +} -- cgit 1.4.1 From e0cebb254e3bbc040791af7c133dbf50c3fc4f72 Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Sun, 1 Oct 2023 22:09:24 +0200 Subject: nixos/c2fmzq-server: init module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Peder Bergebakken Sundt Co-authored-by: Anselm Schüler Co-authored-by: h7x4 --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/c2fmzq-server.md | 42 ++++++++ nixos/modules/services/web-apps/c2fmzq-server.nix | 125 ++++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 nixos/modules/services/web-apps/c2fmzq-server.md create mode 100644 nixos/modules/services/web-apps/c2fmzq-server.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index c3cb495498d..822ba67a40d 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -125,6 +125,8 @@ - [Rosenpass](https://rosenpass.eu/), a service for post-quantum-secure VPNs with WireGuard. Available as [services.rosenpass](#opt-services.rosenpass.enable). +- [c2FmZQ](https://github.com/c2FmZQ/c2FmZQ/), an application that can securely encrypt, store, and share files, including but not limited to pictures and videos. Available as [services.c2fmzq-server](#opt-services.c2fmzq-server.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - `network-online.target` has been fixed to no longer time out for systems with `networking.useDHCP = true` and `networking.useNetworkd = true`. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index bf24ee7603f..4d8fa8159a8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1232,6 +1232,7 @@ ./services/web-apps/atlassian/jira.nix ./services/web-apps/audiobookshelf.nix ./services/web-apps/bookstack.nix + ./services/web-apps/c2fmzq-server.nix ./services/web-apps/calibre-web.nix ./services/web-apps/coder.nix ./services/web-apps/changedetection-io.nix diff --git a/nixos/modules/services/web-apps/c2fmzq-server.md b/nixos/modules/services/web-apps/c2fmzq-server.md new file mode 100644 index 00000000000..236953bd4ff --- /dev/null +++ b/nixos/modules/services/web-apps/c2fmzq-server.md @@ -0,0 +1,42 @@ +# c2FmZQ {#module-services-c2fmzq} + +c2FmZQ is an application that can securely encrypt, store, and share files, +including but not limited to pictures and videos. + +The service `c2fmzq-server` can be enabled by setting +``` +{ + services.c2fmzq-server.enable = true; +} +``` +This will spin up an instance of the server which is API-compatible with +[Stingle Photos](https://stingle.org) and an experimental Progressive Web App +(PWA) to interact with the storage via the browser. + +In principle the server can be exposed directly on a public interface and there +are command line options to manage HTTPS certificates directly, but the module +is designed to be served behind a reverse proxy or only accessed via localhost. + +``` +{ + services.c2fmzq-server = { + enable = true; + bindIP = "127.0.0.1"; # default + port = 8080; # default + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts."example.com" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:8080"; + }; + }; + }; +} +``` + +For more information, see . diff --git a/nixos/modules/services/web-apps/c2fmzq-server.nix b/nixos/modules/services/web-apps/c2fmzq-server.nix new file mode 100644 index 00000000000..2749c2a5a87 --- /dev/null +++ b/nixos/modules/services/web-apps/c2fmzq-server.nix @@ -0,0 +1,125 @@ +{ lib, pkgs, config, ... }: + +let + inherit (lib) mkEnableOption mkPackageOption mkOption types; + + cfg = config.services.c2fmzq-server; + + argsFormat = { + type = with lib.types; nullOr (oneOf [ bool int str ]); + generate = lib.cli.toGNUCommandLineShell { }; + }; +in { + options.services.c2fmzq-server = { + enable = mkEnableOption "c2fmzq-server"; + + bindIP = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "The local address to use."; + }; + + port = mkOption { + type = types.port; + default = 8080; + description = "The local port to use."; + }; + + passphraseFile = mkOption { + type = types.str; + example = "/run/secrets/c2fmzq/pwfile"; + description = "Path to file containing the database passphrase"; + }; + + package = mkPackageOption pkgs "c2fmzq" { }; + + settings = mkOption { + type = types.submodule { + freeformType = argsFormat.type; + + options = { + address = mkOption { + internal = true; + type = types.str; + default = "${cfg.bindIP}:${toString cfg.port}"; + }; + + database = mkOption { + type = types.str; + default = "%S/c2fmzq-server/data"; + description = "Path of the database"; + }; + + verbose = mkOption { + type = types.ints.between 1 3; + default = 2; + description = "The level of logging verbosity: 1:Error 2:Info 3:Debug"; + }; + }; + }; + description = '' + Configuration for c2FmZQ-server passed as CLI arguments. + Run {command}`c2FmZQ-server help` for supported values. + ''; + example = { + verbose = 3; + allow-new-accounts = true; + auto-approve-new-accounts = true; + encrypt-metadata = true; + enable-webapp = true; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.c2fmzq-server = { + description = "c2FmZQ-server"; + documentation = [ "https://github.com/c2FmZQ/c2FmZQ/blob/main/README.md" ]; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "network-online.target" ]; + + serviceConfig = { + ExecStart = "${lib.getExe cfg.package} ${argsFormat.generate cfg.settings}"; + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + DynamicUser = true; + Environment = "C2FMZQ_PASSPHRASE_FILE=%d/passphrase-file"; + IPAccounting = true; + IPAddressAllow = cfg.bindIP; + IPAddressDeny = "any"; + LoadCredential = "passphrase-file:${cfg.passphraseFile}"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateIPC = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SocketBindAllow = cfg.port; + SocketBindDeny = "any"; + StateDirectory = "c2fmzq-server"; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged @obsolete" ]; + }; + }; + }; + + meta = { + doc = ./c2fmzq-server.md; + maintainers = with lib.maintainers; [ hmenke ]; + }; +} -- cgit 1.4.1 From b3c1d8c9aea817c66e8a6384a345390ac36f40eb Mon Sep 17 00:00:00 2001 From: nikstur Date: Sat, 14 Oct 2023 01:29:05 +0200 Subject: nixos: add system.switch.enable flag This flag allows the user to optionally exclude switch-to-confguration.pl from toplevel. This is interesting for appliance images where you don't want to re-build the system. This flag is called `rebuildable` because the standard interface to do this is `nixos-rebuild` which will not work anymore with this change. --- nixos/modules/module-list.nix | 1 + .../system/activation/activatable-system.nix | 65 +++++++++------------- .../system/activation/switchable-system.nix | 55 ++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/non-switchable-system.nix | 15 +++++ 5 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 nixos/modules/system/activation/switchable-system.nix create mode 100644 nixos/tests/non-switchable-system.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2c06f493172..496943ad33a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1392,6 +1392,7 @@ ./system/activation/activatable-system.nix ./system/activation/activation-script.nix ./system/activation/specialisation.nix + ./system/activation/switchable-system.nix ./system/activation/bootspec.nix ./system/activation/top-level.nix ./system/boot/binfmt.nix diff --git a/nixos/modules/system/activation/activatable-system.nix b/nixos/modules/system/activation/activatable-system.nix index 7f6154794bd..3d941596747 100644 --- a/nixos/modules/system/activation/activatable-system.nix +++ b/nixos/modules/system/activation/activatable-system.nix @@ -1,52 +1,16 @@ -{ config, lib, pkgs, ... }: +{ options, config, lib, pkgs, ... }: let inherit (lib) mkOption - optionalString types ; - perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]); - systemBuilderArgs = { activationScript = config.system.activationScripts.script; dryActivationScript = config.system.dryActivationScript; }; - systemBuilderCommands = '' - echo "$activationScript" > $out/activate - echo "$dryActivationScript" > $out/dry-activate - substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar} - substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar} - chmod u+x $out/activate $out/dry-activate - unset activationScript dryActivationScript - - mkdir $out/bin - substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \ - --subst-var out \ - --subst-var-by toplevel ''${!toplevelVar} \ - --subst-var-by coreutils "${pkgs.coreutils}" \ - --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \ - --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \ - --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \ - --subst-var-by perl "${perlWrapped}" \ - --subst-var-by shell "${pkgs.bash}/bin/sh" \ - --subst-var-by su "${pkgs.shadow.su}/bin/su" \ - --subst-var-by systemd "${config.systemd.package}" \ - --subst-var-by utillinux "${pkgs.util-linux}" \ - ; - - chmod +x $out/bin/switch-to-configuration - ${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) '' - if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then - echo "switch-to-configuration syntax is not valid:" - echo "$output" - exit 1 - fi - ''} - ''; - in { options = { @@ -60,6 +24,18 @@ in do, but for image based systems, this may not be needed or not be desirable. ''; }; + system.activatableSystemBuilderCommands = options.system.systemBuilderCommands // { + description = lib.mdDoc '' + Like `system.systemBuilderCommands`, but only for the commands that are + needed *both* when the system is activatable and when it isn't. + + Disclaimer: This option might go away in the future. It might be + superseded by separating switch-to-configuration into a separate script + which will make this option superfluous. See + https://github.com/NixOS/nixpkgs/pull/263462#discussion_r1373104845 for + a discussion. + ''; + }; system.build.separateActivationScript = mkOption { type = types.package; description = '' @@ -71,7 +47,18 @@ in }; }; config = { - system.systemBuilderCommands = lib.mkIf config.system.activatable systemBuilderCommands; + system.activatableSystemBuilderCommands = '' + echo "$activationScript" > $out/activate + echo "$dryActivationScript" > $out/dry-activate + substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar} + substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar} + chmod u+x $out/activate $out/dry-activate + unset activationScript dryActivationScript + ''; + + system.systemBuilderCommands = lib.mkIf + config.system.activatable + config.system.activatableSystemBuilderCommands; system.systemBuilderArgs = lib.mkIf config.system.activatable (systemBuilderArgs // { toplevelVar = "out"; @@ -86,7 +73,7 @@ in }) '' mkdir $out - ${systemBuilderCommands} + ${config.system.activatableSystemBuilderCommands} ''; }; } diff --git a/nixos/modules/system/activation/switchable-system.nix b/nixos/modules/system/activation/switchable-system.nix new file mode 100644 index 00000000000..00bc18e48d1 --- /dev/null +++ b/nixos/modules/system/activation/switchable-system.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +let + + perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]); + +in + +{ + + options = { + system.switch.enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc '' + Whether to include the capability to switch configurations. + + Disabling this makes the system unable to be reconfigured via `nixos-rebuild`. + + This is good for image based appliances where updates are handled + outside the image. Reducing features makes the image lighter and + slightly more secure. + ''; + }; + }; + + config = lib.mkIf config.system.switch.enable { + system.activatableSystemBuilderCommands = '' + mkdir $out/bin + substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \ + --subst-var out \ + --subst-var-by toplevel ''${!toplevelVar} \ + --subst-var-by coreutils "${pkgs.coreutils}" \ + --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \ + --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \ + --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \ + --subst-var-by perl "${perlWrapped}" \ + --subst-var-by shell "${pkgs.bash}/bin/sh" \ + --subst-var-by su "${pkgs.shadow.su}/bin/su" \ + --subst-var-by systemd "${config.systemd.package}" \ + --subst-var-by utillinux "${pkgs.util-linux}" \ + ; + + chmod +x $out/bin/switch-to-configuration + ${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) '' + if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then + echo "switch-to-configuration syntax is not valid:" + echo "$output" + exit 1 + fi + ''} + ''; + }; + +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 22371c9fec3..5098b4dfb1e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -571,6 +571,7 @@ in { node-red = handleTest ./node-red.nix {}; nomad = handleTest ./nomad.nix {}; non-default-filesystems = handleTest ./non-default-filesystems.nix {}; + non-switchable-system = runTest ./non-switchable-system.nix; noto-fonts = handleTest ./noto-fonts.nix {}; noto-fonts-cjk-qt-default-weight = handleTest ./noto-fonts-cjk-qt-default-weight.nix {}; novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {}; diff --git a/nixos/tests/non-switchable-system.nix b/nixos/tests/non-switchable-system.nix new file mode 100644 index 00000000000..54bede75453 --- /dev/null +++ b/nixos/tests/non-switchable-system.nix @@ -0,0 +1,15 @@ +{ lib, ... }: + +{ + name = "non-switchable-system"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { + system.switch.enable = false; + }; + + testScript = '' + machine.succeed("test ! -e /run/current-system/bin/switch-to-configuration") + ''; +} -- cgit 1.4.1 From 3a2d3bc3d82bc389ed8d5ce9dba87c9c60dce280 Mon Sep 17 00:00:00 2001 From: Anthony Roussel Date: Wed, 25 Oct 2023 13:54:42 +0200 Subject: nixos/goss: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/monitoring/goss.md | 44 ++++++++++++ nixos/modules/services/monitoring/goss.nix | 86 +++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 nixos/modules/services/monitoring/goss.md create mode 100644 nixos/modules/services/monitoring/goss.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 822ba67a40d..4aac742160b 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -86,6 +86,8 @@ - [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable). +- [Goss](https://goss.rocks/), a YAML based serverspec alternative tool for validating a server's configuration. Available as [services.goss](#opt-services.goss.enable). + - [trust-dns](https://trust-dns.org/), a Rust based DNS server built to be safe and secure from the ground up. Available as [services.trust-dns](#opt-services.trust-dns.enable). - [osquery](https://www.osquery.io/), a SQL powered operating system instrumentation, monitoring, and analytics. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4d8fa8159a8..95b1dce70f9 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -773,6 +773,7 @@ ./services/monitoring/datadog-agent.nix ./services/monitoring/do-agent.nix ./services/monitoring/fusion-inventory.nix + ./services/monitoring/goss.nix ./services/monitoring/grafana-agent.nix ./services/monitoring/grafana-image-renderer.nix ./services/monitoring/grafana-reporter.nix diff --git a/nixos/modules/services/monitoring/goss.md b/nixos/modules/services/monitoring/goss.md new file mode 100644 index 00000000000..1e636aa3bdf --- /dev/null +++ b/nixos/modules/services/monitoring/goss.md @@ -0,0 +1,44 @@ +# Goss {#module-services-goss} + +[goss](https://goss.rocks/) is a YAML based serverspec alternative tool +for validating a server's configuration. + +## Basic Usage {#module-services-goss-basic-usage} + +A minimal configuration looks like this: + +``` +{ + services.goss = { + enable = true; + + environment = { + GOSS_FMT = "json"; + GOSS_LOGLEVEL = "TRACE"; + }; + + settings = { + addr."tcp://localhost:8080" = { + reachable = true; + local-address = "127.0.0.1"; + }; + command."check-goss-version" = { + exec = "${lib.getExe pkgs.goss} --version"; + exit-status = 0; + }; + dns.localhost.resolvable = true; + file."/nix" = { + filetype = "directory"; + exists = true; + }; + group.root.exists = true; + kernel-param."kernel.ostype".value = "Linux"; + service.goss = { + enabled = true; + running = true; + }; + user.root.exists = true; + }; + }; +} +``` diff --git a/nixos/modules/services/monitoring/goss.nix b/nixos/modules/services/monitoring/goss.nix new file mode 100644 index 00000000000..64a8dad0703 --- /dev/null +++ b/nixos/modules/services/monitoring/goss.nix @@ -0,0 +1,86 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.goss; + + settingsFormat = pkgs.formats.yaml { }; + configFile = settingsFormat.generate "goss.yaml" cfg.settings; + +in { + meta = { + doc = ./goss.md; + maintainers = [ lib.maintainers.anthonyroussel ]; + }; + + options = { + services.goss = { + enable = lib.mkEnableOption (lib.mdDoc "Goss daemon"); + + package = lib.mkPackageOptionMD pkgs "goss" { }; + + environment = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + example = { + GOSS_FMT = "json"; + GOSS_LOGLEVEL = "FATAL"; + GOSS_LISTEN = ":8080"; + }; + description = lib.mdDoc '' + Environment variables to set for the goss service. + + See + ''; + }; + + settings = lib.mkOption { + type = lib.types.submodule { freeformType = settingsFormat.type; }; + default = { }; + example = { + addr."tcp://localhost:8080" = { + reachable = true; + local-address = "127.0.0.1"; + }; + service.goss = { + enabled = true; + running = true; + }; + }; + description = lib.mdDoc '' + The global options in `config` file in yaml format. + + Refer to for schema. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.services.goss = { + description = "Goss - Quick and Easy server validation"; + unitConfig.Documentation = "https://github.com/goss-org/goss/blob/master/docs/manual.md"; + + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + + environment = { + GOSS_FILE = configFile; + } // cfg.environment; + + reloadTriggers = [ configFile ]; + + serviceConfig = { + DynamicUser = true; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + ExecStart = "${cfg.package}/bin/goss serve"; + Group = "goss"; + Restart = "on-failure"; + RestartSec = 5; + User = "goss"; + }; + }; + }; +} -- cgit 1.4.1 From f4aeeb9e81cc57cd76fd55dcae78dc95cb1ca6b7 Mon Sep 17 00:00:00 2001 From: chayleaf Date: Mon, 23 Oct 2023 18:25:38 +0700 Subject: nixos/certspotter: init --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/monitoring/certspotter.md | 74 +++++++++++ nixos/modules/services/monitoring/certspotter.nix | 143 ++++++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 nixos/modules/services/monitoring/certspotter.md create mode 100644 nixos/modules/services/monitoring/certspotter.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index a3170860b13..bcb949fdb30 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -111,6 +111,8 @@ - [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers. +- [certspotter](https://github.com/SSLMate/certspotter), a certificate transparency log monitor. Available as [services.certspotter](#opt-services.certspotter.enable). + - [audiobookshelf](https://github.com/advplyr/audiobookshelf/), a self-hosted audiobook and podcast server. Available as [services.audiobookshelf](#opt-services.audiobookshelf.enable). - [ZITADEL](https://zitadel.com), a turnkey identity and access management platform. Available as [services.zitadel](#opt-services.zitadel.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ebca1ef62a5..09ed28d7af2 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -766,6 +766,7 @@ ./services/monitoring/below.nix ./services/monitoring/bosun.nix ./services/monitoring/cadvisor.nix + ./services/monitoring/certspotter.nix ./services/monitoring/cockpit.nix ./services/monitoring/collectd.nix ./services/monitoring/das_watchdog.nix diff --git a/nixos/modules/services/monitoring/certspotter.md b/nixos/modules/services/monitoring/certspotter.md new file mode 100644 index 00000000000..9bf6e1d946a --- /dev/null +++ b/nixos/modules/services/monitoring/certspotter.md @@ -0,0 +1,74 @@ +# Cert Spotter {#module-services-certspotter} + +Cert Spotter is a tool for monitoring [Certificate Transparency](https://en.wikipedia.org/wiki/Certificate_Transparency) +logs. + +## Service Configuration {#modules-services-certspotter-service-configuration} + +A basic config that notifies you of all certificate changes for your +domain would look as follows: + +```nix +services.certspotter = { + enable = true; + # replace example.org with your domain name + watchlist = [ ".example.org" ]; + emailRecipients = [ "webmaster@example.org" ]; +}; + +# Configure an SMTP client +programs.msmtp.enable = true; +# Or you can use any other module that provides sendmail, like +# services.nullmailer, services.opensmtpd, services.postfix +``` + +In this case, the leading dot in `".example.org"` means that Cert +Spotter should monitor not only `example.org`, but also all of its +subdomains. + +## Operation {#modules-services-certspotter-operation} + +**By default, NixOS configures Cert Spotter to skip all certificates +issued before its first launch**, because checking the entire +Certificate Transparency logs requires downloading tens of terabytes of +data. If you want to check the *entire* logs for previously issued +certificates, you have to set `services.certspotter.startAtEnd` to +`false` and remove all previously saved log state in +`/var/lib/certspotter/logs`. The downloaded logs aren't saved, so if you +add a new domain to the watchlist and want Cert Spotter to go through +the logs again, you will have to remove `/var/lib/certspotter/logs` +again. + +After catching up with the logs, Cert Spotter will start monitoring live +logs. As of October 2023, it uses around **20 Mbps** of traffic on +average. + +## Hooks {#modules-services-certspotter-hooks} + +Cert Spotter supports running custom hooks instead of (or in addition +to) sending emails. Hooks are shell scripts that will be passed certain +environment variables. + +To see hook documentation, see Cert Spotter's man pages: + +```ShellSession +nix-shell -p certspotter --run 'man 8 certspotter-script' +``` + +For example, you can remove `emailRecipients` and send email +notifications manually using the following hook: + +```nix +services.certspotter.hooks = [ + (pkgs.writeShellScript "certspotter-hook" '' + function print_email() { + echo "Subject: [certspotter] $SUMMARY" + echo "Mime-Version: 1.0" + echo "Content-Type: text/plain; charset=US-ASCII" + echo + cat "$TEXT_FILENAME" + } + print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org + '') +]; +``` diff --git a/nixos/modules/services/monitoring/certspotter.nix b/nixos/modules/services/monitoring/certspotter.nix new file mode 100644 index 00000000000..aafa29daa87 --- /dev/null +++ b/nixos/modules/services/monitoring/certspotter.nix @@ -0,0 +1,143 @@ +{ config +, lib +, pkgs +, ... }: + +let + cfg = config.services.certspotter; + + configDir = pkgs.linkFarm "certspotter-config" ( + lib.toList { + name = "watchlist"; + path = pkgs.writeText "certspotter-watchlist" (builtins.concatStringsSep "\n" cfg.watchlist); + } + ++ lib.optional (cfg.emailRecipients != [ ]) { + name = "email_recipients"; + path = pkgs.writeText "certspotter-email_recipients" (builtins.concatStringsSep "\n" cfg.emailRecipients); + } + # always generate hooks dir when no emails are provided to allow running cert spotter with no hooks/emails + ++ lib.optional (cfg.emailRecipients == [ ] || cfg.hooks != [ ]) { + name = "hooks.d"; + path = pkgs.linkFarm "certspotter-hooks" (lib.imap1 (i: path: { + inherit path; + name = "hook${toString i}"; + }) cfg.hooks); + }); +in +{ + options.services.certspotter = { + enable = lib.mkEnableOption "Cert Spotter, a Certificate Transparency log monitor"; + + package = lib.mkPackageOptionMD pkgs "certspotter" { }; + + startAtEnd = lib.mkOption { + type = lib.types.bool; + description = '' + Whether to skip certificates issued before the first launch of Cert Spotter. + Setting this to `false` will cause Cert Spotter to download tens of terabytes of data. + ''; + default = true; + }; + + sendmailPath = lib.mkOption { + type = with lib.types; nullOr path; + description = '' + Path to the `sendmail` binary. By default, the local sendmail wrapper is used + (see {option}`services.mail.sendmailSetuidWrapper`}). + ''; + example = lib.literalExpression ''"''${pkgs.system-sendmail}/bin/sendmail"''; + }; + + watchlist = lib.mkOption { + type = with lib.types; listOf str; + description = "Domain names to watch. To monitor a domain with all subdomains, prefix its name with `.` (e.g. `.example.org`)."; + default = [ ]; + example = [ ".example.org" "another.example.com" ]; + }; + + emailRecipients = lib.mkOption { + type = with lib.types; listOf str; + description = "A list of email addresses to send certificate updates to."; + default = [ ]; + }; + + hooks = lib.mkOption { + type = with lib.types; listOf path; + description = '' + Scripts to run upon the detection of a new certificate. See `man 8 certspotter-script` or + [the GitHub page](https://github.com/SSLMate/certspotter/blob/${pkgs.certspotter.src.rev or "master"}/man/certspotter-script.md) + for more info. + ''; + default = [ ]; + example = lib.literalExpression '' + [ + (pkgs.writeShellScript "certspotter-hook" ''' + echo "Event summary: $SUMMARY." + ''') + ] + ''; + }; + + extraFlags = lib.mkOption { + type = with lib.types; listOf str; + description = "Extra command-line arguments to pass to Cert Spotter"; + example = [ "-no_save" ]; + default = [ ]; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = (cfg.emailRecipients != [ ]) -> (cfg.sendmailPath != null); + message = '' + You must configure the sendmail setuid wrapper (services.mail.sendmailSetuidWrapper) + or services.certspotter.sendmailPath + ''; + } + ]; + + services.certspotter.sendmailPath = let + inherit (config.security) wrapperDir; + inherit (config.services.mail) sendmailSetuidWrapper; + in lib.mkMerge [ + (lib.mkIf (sendmailSetuidWrapper != null) (lib.mkOptionDefault "${wrapperDir}/${sendmailSetuidWrapper.program}")) + (lib.mkIf (sendmailSetuidWrapper == null) (lib.mkOptionDefault null)) + ]; + + users.users.certspotter = { + description = "Cert Spotter user"; + group = "certspotter"; + home = "/var/lib/certspotter"; + isSystemUser = true; + }; + users.groups.certspotter = { }; + + systemd.services.certspotter = { + description = "Cert Spotter - Certificate Transparency Monitor"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment.CERTSPOTTER_CONFIG_DIR = configDir; + environment.SENDMAIL_PATH = if cfg.sendmailPath != null then cfg.sendmailPath else "/run/current-system/sw/bin/false"; + script = '' + export CERTSPOTTER_STATE_DIR="$STATE_DIRECTORY" + cd "$CERTSPOTTER_STATE_DIR" + ${lib.optionalString cfg.startAtEnd '' + if [[ ! -d logs ]]; then + # Don't download certificates issued before the first launch + exec ${cfg.package}/bin/certspotter -start_at_end ${lib.escapeShellArgs cfg.extraFlags} + fi + ''} + exec ${cfg.package}/bin/certspotter ${lib.escapeShellArgs cfg.extraFlags} + ''; + serviceConfig = { + User = "certspotter"; + Group = "certspotter"; + StateDirectory = "certspotter"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ chayleaf ]; + meta.doc = ./certspotter.md; +} -- cgit 1.4.1 From fa54eeea5c23f3dc826d1e6cd9d6dd29b48b1937 Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Tue, 24 Oct 2023 17:53:12 +0100 Subject: livebook: add systemd user service, test, and docs Co-authored-by: Yt --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/development/livebook.md | 39 ++++++++++ nixos/modules/services/development/livebook.nix | 90 +++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/livebook-service.nix | 43 +++++++++++ pkgs/servers/web-apps/livebook/default.nix | 6 +- 7 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/services/development/livebook.md create mode 100644 nixos/modules/services/development/livebook.nix create mode 100644 nixos/tests/livebook-service.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index dc8f989c686..7af4a99906c 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -72,6 +72,8 @@ - [LibreNMS](https://www.librenms.org), a auto-discovering PHP/MySQL/SNMP based network monitoring. Available as [services.librenms](#opt-services.librenms.enable). +- [Livebook](https://livebook.dev/), an interactive notebook with support for Elixir, graphs, machine learning, and more. + - [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable). - [stalwart-mail](https://stalw.art), an all-in-one email server (SMTP, IMAP, JMAP). Available as [services.stalwart-mail](#opt-services.stalwart-mail.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index bfac651f5a8..4949eb6f298 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -485,6 +485,7 @@ ./services/development/hoogle.nix ./services/development/jupyter/default.nix ./services/development/jupyterhub/default.nix + ./services/development/livebook.nix ./services/development/lorri.nix ./services/development/rstudio-server/default.nix ./services/development/zammad.nix diff --git a/nixos/modules/services/development/livebook.md b/nixos/modules/services/development/livebook.md new file mode 100644 index 00000000000..73ddc57f617 --- /dev/null +++ b/nixos/modules/services/development/livebook.md @@ -0,0 +1,39 @@ +# Livebook {#module-services-livebook} + +[Livebook](https://livebook.dev/) is a web application for writing +interactive and collaborative code notebooks. + +## Basic Usage {#module-services-livebook-basic-usage} + +Enabling the `livebook` service creates a user +[`systemd`](https://www.freedesktop.org/wiki/Software/systemd/) unit +which runs the server. + +``` +{ ... }: + +{ + services.livebook = { + enableUserService = true; + port = 20123; + # See note below about security + environmentFile = pkgs.writeText "livebook.env" '' + LIVEBOOK_PASSWORD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + ''; + }; +} +``` + +::: {.note} + +The Livebook server has the ability to run any command as the user it +is running under, so securing access to it with a password is highly +recommended. + +Putting the password in the Nix configuration like above is an easy +way to get started but it is not recommended in the real world because +the `livebook.env` file will be added to the world-readable Nix store. +A better approach would be to put the password in some secure +user-readable location and set `environmentFile = /home/user/secure/livebook.env`. + +::: diff --git a/nixos/modules/services/development/livebook.nix b/nixos/modules/services/development/livebook.nix new file mode 100644 index 00000000000..3991a4125ec --- /dev/null +++ b/nixos/modules/services/development/livebook.nix @@ -0,0 +1,90 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.livebook; +in +{ + options.services.livebook = { + # Since livebook doesn't have a granular permission system (a user + # either has access to all the data or none at all), the decision + # was made to run this as a user service. If that changes in the + # future, this can be changed to a system service. + enableUserService = mkEnableOption "a user service for Livebook"; + + environmentFile = mkOption { + type = types.path; + description = lib.mdDoc '' + Environment file as defined in {manpage}`systemd.exec(5)` passed to the service. + + This must contain at least `LIVEBOOK_PASSWORD` or + `LIVEBOOK_TOKEN_ENABLED=false`. See `livebook server --help` + for other options.''; + }; + + erlang_node_short_name = mkOption { + type = with types; nullOr str; + default = null; + example = "livebook"; + description = "A short name for the distributed node."; + }; + + erlang_node_name = mkOption { + type = with types; nullOr str; + default = null; + example = "livebook@127.0.0.1"; + description = "The name for the app distributed node."; + }; + + port = mkOption { + type = types.port; + default = 8080; + description = "The port to start the web application on."; + }; + + address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = lib.mdDoc '' + The address to start the web application on. Must be a valid IPv4 or + IPv6 address. + ''; + }; + + options = mkOption { + type = with types; attrsOf str; + default = { }; + description = lib.mdDoc '' + Additional options to pass as command-line arguments to the server. + ''; + example = literalExpression '' + { + cookie = "a value shared by all nodes in this cluster"; + } + ''; + }; + }; + + config = mkIf cfg.enableUserService { + systemd.user.services.livebook = { + serviceConfig = { + Restart = "always"; + EnvironmentFile = cfg.environmentFile; + ExecStart = + let + args = lib.cli.toGNUCommandLineShell { } ({ + inherit (cfg) port; + ip = cfg.address; + name = cfg.erlang_node_name; + sname = cfg.erlang_node_short_name; + } // cfg.options); + in + "${pkgs.livebook}/bin/livebook server ${args}"; + }; + path = [ pkgs.bash ]; + wantedBy = [ "default.target" ]; + }; + }; + + meta.doc = ./livebook.md; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 2f6d5a8dae8..851a2cc4e03 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -371,6 +371,7 @@ in { honk = runTest ./honk.nix; installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {}); invidious = handleTest ./invidious.nix {}; + livebook-service = handleTest ./livebook-service.nix {}; oci-containers = handleTestOn ["aarch64-linux" "x86_64-linux"] ./oci-containers.nix {}; odoo = handleTest ./odoo.nix {}; odoo15 = handleTest ./odoo.nix { package = pkgs.odoo15; }; diff --git a/nixos/tests/livebook-service.nix b/nixos/tests/livebook-service.nix new file mode 100644 index 00000000000..9397e3cb75f --- /dev/null +++ b/nixos/tests/livebook-service.nix @@ -0,0 +1,43 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "livebook-service"; + + nodes = { + machine = { config, pkgs, ... }: { + imports = [ + ./common/user-account.nix + ]; + + services.livebook = { + enableUserService = true; + port = 20123; + environmentFile = pkgs.writeText "livebook.env" '' + LIVEBOOK_PASSWORD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + ''; + options = { + cookie = "chocolate chip"; + }; + }; + }; + }; + + testScript = { nodes, ... }: + let + user = nodes.machine.config.users.users.alice; + sudo = lib.concatStringsSep " " [ + "XDG_RUNTIME_DIR=/run/user/${toString user.uid}" + "sudo" + "--preserve-env=XDG_RUNTIME_DIR" + "-u" + "alice" + ]; + in + '' + machine.wait_for_unit("multi-user.target") + + machine.succeed("loginctl enable-linger alice") + machine.wait_until_succeeds("${sudo} systemctl --user is-active livebook.service") + machine.wait_for_open_port(20123) + + machine.succeed("curl -L localhost:20123 | grep 'Type password'") + ''; +}) diff --git a/pkgs/servers/web-apps/livebook/default.nix b/pkgs/servers/web-apps/livebook/default.nix index 511f7b80bc5..dee6017624d 100644 --- a/pkgs/servers/web-apps/livebook/default.nix +++ b/pkgs/servers/web-apps/livebook/default.nix @@ -1,4 +1,4 @@ -{ lib, beamPackages, makeWrapper, rebar3, elixir, erlang, fetchFromGitHub }: +{ lib, beamPackages, makeWrapper, rebar3, elixir, erlang, fetchFromGitHub, nixosTests }: beamPackages.mixRelease rec { pname = "livebook"; version = "0.11.3"; @@ -32,6 +32,10 @@ beamPackages.mixRelease rec { --set MIX_REBAR3 ${rebar3}/bin/rebar3 ''; + passthru.tests = { + livebook-service = nixosTests.livebook-service; + }; + meta = with lib; { license = licenses.asl20; homepage = "https://livebook.dev/"; -- cgit 1.4.1 From 151fa7c39c4b0c765d1ad076afdf042b1517a0ed Mon Sep 17 00:00:00 2001 From: nikstur Date: Tue, 31 Oct 2023 11:25:04 +0100 Subject: nixos/image: include module options in manual --- nixos/modules/module-list.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4949eb6f298..95615c8db54 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1531,5 +1531,9 @@ ./virtualisation/waydroid.nix ./virtualisation/xe-guest-utilities.nix ./virtualisation/xen-dom0.nix - { documentation.nixos.extraModules = [ ./virtualisation/qemu-vm.nix ]; } + { documentation.nixos.extraModules = [ + ./virtualisation/qemu-vm.nix + ./image/repart.nix + ]; + } ] -- cgit 1.4.1 From 5927d556855d43f1d0495f3fb7ee2a287f04d8ce Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 31 Oct 2023 14:12:00 +0100 Subject: privacyidea: remove Related to #262907 (Django3 removal from nixpkgs). This package already required an unreasonable amount of maintenance regularly for a such small leaf-package. It has a few highly outdated dependencies (e.g. flask 1, jinja2 2.11, sqlalchemy 1.3). After at least each Python package-set update one had to fix up a lot of dependencies to fix the package itself, so it was only useful on stable branches. And having so much outdated software in a security-sensitive piece of software seems questionable. Finally, globin and I won't be available for maintaining this now that Mayflower is migrating to another solution (and we'll do that as well) and I'd expect this to bitrot extremely quick if we both bail out. --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 - nixos/modules/services/security/privacyidea.nix | 458 --------------------- nixos/tests/all-tests.nix | 1 - nixos/tests/privacyidea.nix | 43 -- pkgs/applications/misc/privacyidea/default.nix | 263 ------------ .../privacyidea-ldap-proxy/default.nix | 32 -- pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 2 - pkgs/top-level/python-aliases.nix | 2 +- pkgs/top-level/python-packages.nix | 2 - 11 files changed, 4 insertions(+), 803 deletions(-) delete mode 100644 nixos/modules/services/security/privacyidea.nix delete mode 100644 nixos/tests/privacyidea.nix delete mode 100644 pkgs/applications/misc/privacyidea/default.nix delete mode 100644 pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 7af4a99906c..276e7c9384e 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -339,6 +339,8 @@ - `service.borgmatic.settings.location` and `services.borgmatic.configurations..location` are deprecated, please move your options out of sections to the global scope. +- `privacyidea` (and the corresponding `privacyidea-ldap-proxy`) has been removed from nixpkgs because it has severely outdated dependencies that became unmaintainable with nixpkgs' python package-set. + - `dagger` was removed because using a package called `dagger` and packaging it from source violates their trademark policy. - `win-virtio` package was renamed to `virtio-win` to be consistent with the upstream package name. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4949eb6f298..5647e89e541 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1176,7 +1176,6 @@ ./services/security/opensnitch.nix ./services/security/pass-secret-service.nix ./services/security/physlock.nix - ./services/security/privacyidea.nix ./services/security/shibboleth-sp.nix ./services/security/sks.nix ./services/security/sshguard.nix diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix deleted file mode 100644 index 664335cb58e..00000000000 --- a/nixos/modules/services/security/privacyidea.nix +++ /dev/null @@ -1,458 +0,0 @@ -{ config, lib, options, pkgs, ... }: - -with lib; - -let - cfg = config.services.privacyidea; - opt = options.services.privacyidea; - - uwsgi = pkgs.uwsgi.override { plugins = [ "python3" ]; python3 = pkgs.python310; }; - python = uwsgi.python3; - penv = python.withPackages (const [ pkgs.privacyidea ]); - logCfg = pkgs.writeText "privacyidea-log.cfg" '' - [formatters] - keys=detail - - [handlers] - keys=stream - - [formatter_detail] - class=privacyidea.lib.log.SecureFormatter - format=[%(asctime)s][%(process)d][%(thread)d][%(levelname)s][%(name)s:%(lineno)d] %(message)s - - [handler_stream] - class=StreamHandler - level=NOTSET - formatter=detail - args=(sys.stdout,) - - [loggers] - keys=root,privacyidea - - [logger_privacyidea] - handlers=stream - qualname=privacyidea - level=INFO - - [logger_root] - handlers=stream - level=ERROR - ''; - - piCfgFile = pkgs.writeText "privacyidea.cfg" '' - SUPERUSER_REALM = [ '${concatStringsSep "', '" cfg.superuserRealm}' ] - SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2:///privacyidea' - SECRET_KEY = '${cfg.secretKey}' - PI_PEPPER = '${cfg.pepper}' - PI_ENCFILE = '${cfg.encFile}' - PI_AUDIT_KEY_PRIVATE = '${cfg.auditKeyPrivate}' - PI_AUDIT_KEY_PUBLIC = '${cfg.auditKeyPublic}' - PI_LOGCONFIG = '${logCfg}' - ${cfg.extraConfig} - ''; - - renderValue = x: - if isList x then concatMapStringsSep "," (x: ''"${x}"'') x - else if isString x && hasInfix "," x then ''"${x}"'' - else x; - - ldapProxyConfig = pkgs.writeText "ldap-proxy.ini" - (generators.toINI {} - (flip mapAttrs cfg.ldap-proxy.settings - (const (mapAttrs (const renderValue))))); - - privacyidea-token-janitor = pkgs.writeShellScriptBin "privacyidea-token-janitor" '' - exec -a privacyidea-token-janitor \ - /run/wrappers/bin/sudo -u ${cfg.user} \ - env PRIVACYIDEA_CONFIGFILE=${cfg.stateDir}/privacyidea.cfg \ - ${penv}/bin/privacyidea-token-janitor $@ - ''; -in - -{ - options = { - services.privacyidea = { - enable = mkEnableOption (lib.mdDoc "PrivacyIDEA"); - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - example = "/root/privacyidea.env"; - description = lib.mdDoc '' - File to load as environment file. Environment variables - from this file will be interpolated into the config file - using `envsubst` which is helpful for specifying - secrets: - ``` - { services.privacyidea.secretKey = "$SECRET"; } - ``` - - The environment-file can now specify the actual secret key: - ``` - SECRET=veryverytopsecret - ``` - ''; - }; - - stateDir = mkOption { - type = types.str; - default = "/var/lib/privacyidea"; - description = lib.mdDoc '' - Directory where all PrivacyIDEA files will be placed by default. - ''; - }; - - superuserRealm = mkOption { - type = types.listOf types.str; - default = [ "super" "administrators" ]; - description = lib.mdDoc '' - The realm where users are allowed to login as administrators. - ''; - }; - - secretKey = mkOption { - type = types.str; - example = "t0p s3cr3t"; - description = lib.mdDoc '' - This is used to encrypt the auth_token. - ''; - }; - - pepper = mkOption { - type = types.str; - example = "Never know..."; - description = lib.mdDoc '' - This is used to encrypt the admin passwords. - ''; - }; - - encFile = mkOption { - type = types.str; - default = "${cfg.stateDir}/enckey"; - defaultText = literalExpression ''"''${config.${opt.stateDir}}/enckey"''; - description = lib.mdDoc '' - This is used to encrypt the token data and token passwords - ''; - }; - - auditKeyPrivate = mkOption { - type = types.str; - default = "${cfg.stateDir}/private.pem"; - defaultText = literalExpression ''"''${config.${opt.stateDir}}/private.pem"''; - description = lib.mdDoc '' - Private Key for signing the audit log. - ''; - }; - - auditKeyPublic = mkOption { - type = types.str; - default = "${cfg.stateDir}/public.pem"; - defaultText = literalExpression ''"''${config.${opt.stateDir}}/public.pem"''; - description = lib.mdDoc '' - Public key for checking signatures of the audit log. - ''; - }; - - adminPasswordFile = mkOption { - type = types.path; - description = lib.mdDoc "File containing password for the admin user"; - }; - - adminEmail = mkOption { - type = types.str; - example = "admin@example.com"; - description = lib.mdDoc "Mail address for the admin user"; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = lib.mdDoc '' - Extra configuration options for pi.cfg. - ''; - }; - - user = mkOption { - type = types.str; - default = "privacyidea"; - description = lib.mdDoc "User account under which PrivacyIDEA runs."; - }; - - group = mkOption { - type = types.str; - default = "privacyidea"; - description = lib.mdDoc "Group account under which PrivacyIDEA runs."; - }; - - tokenjanitor = { - enable = mkEnableOption (lib.mdDoc "automatic runs of the token janitor"); - interval = mkOption { - default = "quarterly"; - type = types.str; - description = lib.mdDoc '' - Interval in which the cleanup program is supposed to run. - See {manpage}`systemd.time(7)` for further information. - ''; - }; - action = mkOption { - type = types.enum [ "delete" "mark" "disable" "unassign" ]; - description = lib.mdDoc '' - Which action to take for matching tokens. - ''; - }; - unassigned = mkOption { - default = false; - type = types.bool; - description = lib.mdDoc '' - Whether to search for **unassigned** tokens - and apply [](#opt-services.privacyidea.tokenjanitor.action) - onto them. - ''; - }; - orphaned = mkOption { - default = true; - type = types.bool; - description = lib.mdDoc '' - Whether to search for **orphaned** tokens - and apply [](#opt-services.privacyidea.tokenjanitor.action) - onto them. - ''; - }; - }; - - ldap-proxy = { - enable = mkEnableOption (lib.mdDoc "PrivacyIDEA LDAP Proxy"); - - configFile = mkOption { - type = types.nullOr types.path; - default = null; - description = lib.mdDoc '' - Path to PrivacyIDEA LDAP Proxy configuration (proxy.ini). - ''; - }; - - user = mkOption { - type = types.str; - default = "pi-ldap-proxy"; - description = lib.mdDoc "User account under which PrivacyIDEA LDAP proxy runs."; - }; - - group = mkOption { - type = types.str; - default = "pi-ldap-proxy"; - description = lib.mdDoc "Group account under which PrivacyIDEA LDAP proxy runs."; - }; - - settings = mkOption { - type = with types; attrsOf (attrsOf (oneOf [ str bool int (listOf str) ])); - default = {}; - description = lib.mdDoc '' - Attribute-set containing the settings for `privacyidea-ldap-proxy`. - It's possible to pass secrets using env-vars as substitutes and - use the option [](#opt-services.privacyidea.ldap-proxy.environmentFile) - to inject them via `envsubst`. - ''; - }; - - environmentFile = mkOption { - default = null; - type = types.nullOr types.str; - description = lib.mdDoc '' - Environment file containing secrets to be substituted into - [](#opt-services.privacyidea.ldap-proxy.settings). - ''; - }; - }; - }; - }; - - config = mkMerge [ - - (mkIf cfg.enable { - - assertions = [ - { - assertion = cfg.tokenjanitor.enable -> (cfg.tokenjanitor.orphaned || cfg.tokenjanitor.unassigned); - message = '' - privacyidea-token-janitor has no effect if neither orphaned nor unassigned tokens - are to be searched. - ''; - } - ]; - - environment.systemPackages = [ pkgs.privacyidea (hiPrio privacyidea-token-janitor) ]; - - services.postgresql.enable = mkDefault true; - - systemd.services.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable { - environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg"; - path = [ penv ]; - serviceConfig = { - CapabilityBoundingSet = [ "" ]; - ExecStart = "${pkgs.writeShellScript "pi-token-janitor" '' - ${optionalString cfg.tokenjanitor.orphaned '' - echo >&2 "Removing orphaned tokens..." - privacyidea-token-janitor find \ - --orphaned true \ - --action ${cfg.tokenjanitor.action} - ''} - ${optionalString cfg.tokenjanitor.unassigned '' - echo >&2 "Removing unassigned tokens..." - privacyidea-token-janitor find \ - --assigned false \ - --action ${cfg.tokenjanitor.action} - ''} - ''}"; - Group = cfg.group; - LockPersonality = true; - MemoryDenyWriteExecute = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectSystem = "strict"; - ReadWritePaths = cfg.stateDir; - Type = "oneshot"; - User = cfg.user; - WorkingDirectory = cfg.stateDir; - }; - }; - systemd.timers.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable { - wantedBy = [ "timers.target" ]; - timerConfig.OnCalendar = cfg.tokenjanitor.interval; - timerConfig.Persistent = true; - }; - - systemd.services.privacyidea = let - piuwsgi = pkgs.writeText "uwsgi.json" (builtins.toJSON { - uwsgi = { - buffer-size = 8192; - plugins = [ "python3" ]; - pythonpath = "${penv}/${uwsgi.python3.sitePackages}"; - socket = "/run/privacyidea/socket"; - uid = cfg.user; - gid = cfg.group; - chmod-socket = 770; - chown-socket = "${cfg.user}:nginx"; - chdir = cfg.stateDir; - wsgi-file = "${penv}/etc/privacyidea/privacyideaapp.wsgi"; - processes = 4; - harakiri = 60; - reload-mercy = 8; - stats = "/run/privacyidea/stats.socket"; - max-requests = 2000; - limit-as = 1024; - reload-on-as = 512; - reload-on-rss = 256; - no-orphans = true; - vacuum = true; - }; - }); - in { - wantedBy = [ "multi-user.target" ]; - after = [ "postgresql.service" ]; - path = with pkgs; [ openssl ]; - environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg"; - preStart = let - pi-manage = "${config.security.sudo.package}/bin/sudo -u privacyidea -HE ${penv}/bin/pi-manage"; - pgsu = config.services.postgresql.superUser; - psql = config.services.postgresql.package; - in '' - mkdir -p ${cfg.stateDir} /run/privacyidea - chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} /run/privacyidea - umask 077 - ${lib.getBin pkgs.envsubst}/bin/envsubst -o ${cfg.stateDir}/privacyidea.cfg \ - -i "${piCfgFile}" - chown ${cfg.user}:${cfg.group} ${cfg.stateDir}/privacyidea.cfg - if ! test -e "${cfg.stateDir}/db-created"; then - ${config.security.sudo.package}/bin/sudo -u ${pgsu} ${psql}/bin/createuser --no-superuser --no-createdb --no-createrole ${cfg.user} - ${config.security.sudo.package}/bin/sudo -u ${pgsu} ${psql}/bin/createdb --owner ${cfg.user} privacyidea - ${pi-manage} create_enckey - ${pi-manage} create_audit_keys - ${pi-manage} createdb - ${pi-manage} admin add admin -e ${cfg.adminEmail} -p "$(cat ${cfg.adminPasswordFile})" - ${pi-manage} db stamp head -d ${penv}/lib/privacyidea/migrations - touch "${cfg.stateDir}/db-created" - chmod g+r "${cfg.stateDir}/enckey" "${cfg.stateDir}/private.pem" - fi - ${pi-manage} db upgrade -d ${penv}/lib/privacyidea/migrations - ''; - serviceConfig = { - Type = "notify"; - ExecStart = "${uwsgi}/bin/uwsgi --json ${piuwsgi}"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; - ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; - NotifyAccess = "main"; - KillSignal = "SIGQUIT"; - }; - }; - - users.users.privacyidea = mkIf (cfg.user == "privacyidea") { - group = cfg.group; - isSystemUser = true; - }; - - users.groups.privacyidea = mkIf (cfg.group == "privacyidea") {}; - }) - - (mkIf cfg.ldap-proxy.enable { - - assertions = [ - { assertion = let - xor = a: b: a && !b || !a && b; - in xor (cfg.ldap-proxy.settings == {}) (cfg.ldap-proxy.configFile == null); - message = "configFile & settings are mutually exclusive for services.privacyidea.ldap-proxy!"; - } - ]; - - warnings = mkIf (cfg.ldap-proxy.configFile != null) [ - "Using services.privacyidea.ldap-proxy.configFile is deprecated! Use the RFC42-style settings option instead!" - ]; - - systemd.services.privacyidea-ldap-proxy = let - ldap-proxy-env = pkgs.python3.withPackages (ps: [ ps.privacyidea-ldap-proxy ]); - in { - description = "privacyIDEA LDAP proxy"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - User = cfg.ldap-proxy.user; - Group = cfg.ldap-proxy.group; - StateDirectory = "privacyidea-ldap-proxy"; - EnvironmentFile = mkIf (cfg.ldap-proxy.environmentFile != null) - [ cfg.ldap-proxy.environmentFile ]; - ExecStartPre = - "${pkgs.writeShellScript "substitute-secrets-ldap-proxy" '' - umask 0077 - ${pkgs.envsubst}/bin/envsubst \ - -i ${ldapProxyConfig} \ - -o $STATE_DIRECTORY/ldap-proxy.ini - ''}"; - ExecStart = let - configPath = if cfg.ldap-proxy.settings != {} - then "%S/privacyidea-ldap-proxy/ldap-proxy.ini" - else cfg.ldap-proxy.configFile; - in '' - ${ldap-proxy-env}/bin/twistd \ - --nodaemon \ - --pidfile= \ - -u ${cfg.ldap-proxy.user} \ - -g ${cfg.ldap-proxy.group} \ - ldap-proxy \ - -c ${configPath} - ''; - Restart = "always"; - }; - }; - - users.users.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") { - group = cfg.ldap-proxy.group; - isSystemUser = true; - }; - - users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {}; - }) - ]; - -} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 456efe14464..0a3bbf37c6b 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -685,7 +685,6 @@ in { predictable-interface-names = handleTest ./predictable-interface-names.nix {}; printing-socket = handleTest ./printing.nix { socket = true; }; printing-service = handleTest ./printing.nix { socket = false; }; - privacyidea = handleTest ./privacyidea.nix {}; privoxy = handleTest ./privoxy.nix {}; prometheus = handleTest ./prometheus.nix {}; prometheus-exporters = handleTest ./prometheus-exporters.nix {}; diff --git a/nixos/tests/privacyidea.nix b/nixos/tests/privacyidea.nix deleted file mode 100644 index 401ad72c37b..00000000000 --- a/nixos/tests/privacyidea.nix +++ /dev/null @@ -1,43 +0,0 @@ -# Miscellaneous small tests that don't warrant their own VM run. - -import ./make-test-python.nix ({ pkgs, ...} : rec { - name = "privacyidea"; - meta = with pkgs.lib.maintainers; { - maintainers = [ ]; - }; - - nodes.machine = { ... }: { - virtualisation.cores = 2; - - services.privacyidea = { - enable = true; - secretKey = "$SECRET_KEY"; - pepper = "$PEPPER"; - adminPasswordFile = pkgs.writeText "admin-password" "testing"; - adminEmail = "root@localhost"; - - # Don't try this at home! - environmentFile = pkgs.writeText "pi-secrets.env" '' - SECRET_KEY=testing - PEPPER=testing - ''; - }; - services.nginx = { - enable = true; - virtualHosts."_".locations."/".extraConfig = '' - uwsgi_pass unix:/run/privacyidea/socket; - ''; - }; - }; - - testScript = '' - machine.start() - machine.wait_for_unit("multi-user.target") - machine.succeed("curl --fail http://localhost | grep privacyIDEA") - machine.succeed("grep \"SECRET_KEY = 'testing'\" /var/lib/privacyidea/privacyidea.cfg") - machine.succeed("grep \"PI_PEPPER = 'testing'\" /var/lib/privacyidea/privacyidea.cfg") - machine.succeed( - "curl --fail http://localhost/auth -F username=admin -F password=testing | grep token" - ) - ''; -}) diff --git a/pkgs/applications/misc/privacyidea/default.nix b/pkgs/applications/misc/privacyidea/default.nix deleted file mode 100644 index 9cdf4da33ef..00000000000 --- a/pkgs/applications/misc/privacyidea/default.nix +++ /dev/null @@ -1,263 +0,0 @@ -{ lib, fetchFromGitHub, cacert, openssl, nixosTests -, python310, fetchPypi, fetchpatch -}: - -let - dropDocOutput = { outputs, ... }: { - outputs = lib.filter (x: x != "doc") outputs; - }; - - # Follow issue below for Python 3.11 support - # https://github.com/privacyidea/privacyidea/issues/3593 - python3' = python310.override { - packageOverrides = self: super: { - django = super.django_3; - - sqlalchemy = super.sqlalchemy.overridePythonAttrs (oldAttrs: rec { - version = "1.3.24"; - src = fetchPypi { - inherit (oldAttrs) pname; - inherit version; - hash = "sha256-67t3fL+TEjWbiXv4G6ANrg9ctp+6KhgmXcwYpvXvdRk="; - }; - doCheck = false; - }); - # version 3.3.0+ does not support SQLAlchemy 1.3 - factory-boy = super.factory-boy.overridePythonAttrs (oldAttrs: rec { - version = "3.2.1"; - src = oldAttrs.src.override { - inherit version; - hash = "sha256-qY0newwEfHXrbkq4UIp/gfsD0sshmG9ieRNUbveipV4="; - }; - postPatch = ""; - }); - # fails with `no tests ran in 1.75s` - alembic = super.alembic.overridePythonAttrs (lib.const { - doCheck = false; - }); - flask-migrate = super.flask-migrate.overridePythonAttrs (oldAttrs: rec { - version = "2.7.0"; - src = fetchPypi { - pname = "Flask-Migrate"; - inherit version; - hash = "sha256-ri8FZxWIdi3YOiHYsYxR/jVehng+JFlJlf+Nc4Df/jg="; - }; - }); - flask-sqlalchemy = super.flask-sqlalchemy.overridePythonAttrs (old: rec { - version = "2.5.1"; - format = "setuptools"; - src = fetchPypi { - pname = "Flask-SQLAlchemy"; - inherit version; - hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912"; - }; - }); - # Taken from by https://github.com/NixOS/nixpkgs/pull/173090/commits/d2c0c7eb4cc91beb0a1adbaf13abc0a526a21708 - werkzeug = super.werkzeug.overridePythonAttrs (old: rec { - version = "1.0.1"; - src = old.src.override { - inherit version; - hash = "sha256-bICx5a02ZSkOo5MguR4b4eDV9gZSuWSjBwIW3oPS5Hw="; - }; - nativeCheckInputs = old.nativeCheckInputs ++ (with self; [ - requests - ]); - doCheck = false; - }); - # Required by flask-1.1 - jinja2 = super.jinja2.overridePythonAttrs (old: rec { - version = "2.11.3"; - src = old.src.override { - inherit version; - hash = "sha256-ptWEM94K6AA0fKsfowQ867q+i6qdKeZo8cdoy4ejM8Y="; - }; - patches = [ - # python 3.10 compat fixes. In later upstream releases, but these - # are not compatible with flask 1 which we need here :( - (fetchpatch { - url = "https://github.com/thmo/jinja/commit/1efb4cc918b4f3d097c376596da101de9f76585a.patch"; - hash = "sha256-GFaSvYxgzOEFmnnDIfcf0ImScNTh1lR4lxt2Uz1DYdU="; - }) - (fetchpatch { - url = "https://github.com/mkrizek/jinja/commit/bd8bad37d1c0e2d8995a44fd88e234f5340afec5.patch"; - hash = "sha256-Uow+gaO+/dH6zavC0X/SsuMAfhTLRWpamVlL87DXDRA="; - excludes = [ "CHANGES.rst" ]; - }) - ]; - }); - # Required by jinja2-2.11.3 - markupsafe = super.markupsafe.overridePythonAttrs (old: rec { - version = "2.0.1"; - src = old.src.override { - inherit version; - hash = "sha256-WUxngH+xYjizDES99082wCzfItHIzake+KDtjav1Ygo="; - }; - }); - itsdangerous = super.itsdangerous.overridePythonAttrs (old: rec { - version = "1.1.0"; - src = old.src.override { - inherit version; - hash = "sha256-MhsDPQfypBNtPsdi6snxahDM1g9TwMka+QIXrOe6Hxk="; - }; - }); - flask = super.flask.overridePythonAttrs (old: rec { - version = "1.1.4"; - src = old.src.override { - inherit version; - hash = "sha256-D762GA04OpGG0NbtlU4AQq2fGODo3giLK0GdUmkn0ZY="; - }; - }); - sqlsoup = super.sqlsoup.overrideAttrs ({ meta ? {}, ... }: { - meta = meta // { broken = false; }; - }); - click = super.click.overridePythonAttrs (old: rec { - version = "7.1.2"; - src = old.src.override { - inherit version; - hash = "sha256-0rUlXHxjSbwb0eWeCM0SrLvWPOZJ8liHVXg6qU37axo="; - }; - disabledTests = [ "test_bytes_args" ]; # https://github.com/pallets/click/commit/6e05e1fa1c2804 - }); - # Now requires `lingua` as check input that requires a newer `click`, - # however `click-7` is needed by the older flask we need here. Since it's just - # for the test-suite apparently, let's skip it for now. - mako = super.mako.overridePythonAttrs (lib.const { - nativeCheckInputs = []; - doCheck = false; - }); - # Requires pytest-httpserver as checkInput now which requires Werkzeug>=2 which is not - # supported by current privacyIDEA. - responses = super.responses.overridePythonAttrs (lib.const { - doCheck = false; - }); - flask-babel = (super.flask-babel.override { - sphinxHook = null; - furo = null; - }).overridePythonAttrs (old: (dropDocOutput old) // rec { - pname = "Flask-Babel"; - version = "2.0.0"; - format = "setuptools"; - src = fetchPypi { - inherit pname; - inherit version; - hash = "sha256:f9faf45cdb2e1a32ea2ec14403587d4295108f35017a7821a2b1acb8cfd9257d"; - }; - disabledTests = [ - # AssertionError: assert 'Apr 12, 2010...46:00\u202fPM' == 'Apr 12, 2010, 1:46:00 PM' - # Note the `\u202f` (narrow, no-break space) vs space. - "test_basics" - "test_init_app" - "test_custom_locale_selector" - "test_refreshing" - ]; - }); - psycopg2 = (super.psycopg2.override { - sphinxHook = null; - sphinx-better-theme = null; - }).overridePythonAttrs dropDocOutput; - pyjwt = (super.pyjwt.override { - sphinxHook = null; - sphinx-rtd-theme = null; - }).overridePythonAttrs (old: (dropDocOutput old) // { format = "setuptools"; }); - beautifulsoup4 = (super.beautifulsoup4.override { - sphinxHook = null; - }).overridePythonAttrs dropDocOutput; - pydash = (super.pydash.override { - sphinx-rtd-theme = null; - }).overridePythonAttrs (old: rec { - version = "5.1.0"; - src = fetchPypi { - inherit (old) pname; - inherit version; - hash = "sha256-GysFCsG64EnNB/WSCxT6u+UmOPSF2a2h6xFanuv/aDU="; - }; - format = "setuptools"; - doCheck = false; - }); - pyopenssl = (super.pyopenssl.override { - sphinxHook = null; - sphinx-rtd-theme = null; - }).overridePythonAttrs dropDocOutput; - deprecated = (super.deprecated.override { - sphinxHook = null; - }).overridePythonAttrs dropDocOutput; - wrapt = (super.wrapt.override { - sphinxHook = null; - sphinx-rtd-theme = null; - }).overridePythonAttrs dropDocOutput; - }; - }; -in -python3'.pkgs.buildPythonPackage rec { - pname = "privacyIDEA"; - version = "3.8.1"; - format = "setuptools"; - - src = fetchFromGitHub { - owner = pname; - repo = pname; - rev = "v${version}"; - hash = "sha256-SYXw8PBCb514v3rcy15W/vZS5JyMsu81D2sJmviLRtw="; - fetchSubmodules = true; - }; - - patches = [ - # https://github.com/privacyidea/privacyidea/pull/3611 - (fetchpatch { - url = "https://github.com/privacyidea/privacyidea/commit/7db6509721726a34e8528437ddbd4210019b11ef.patch"; - sha256 = "sha256-ZvtauCs1vWyxzGbA0B2+gG8q5JyUO8DF8nm/3/vcYmE="; - }) - ]; - - propagatedBuildInputs = with python3'.pkgs; [ - cryptography pyrad pymysql python-dateutil flask-versioned flask-script - defusedxml croniter flask-migrate pyjwt configobj sqlsoup pillow - python-gnupg passlib pyopenssl beautifulsoup4 smpplib flask-babel - ldap3 huey pyyaml qrcode oauth2client requests lxml cbor2 psycopg2 - pydash ecdsa google-auth importlib-metadata argon2-cffi bcrypt segno - ]; - - passthru.tests = { inherit (nixosTests) privacyidea; }; - - nativeCheckInputs = with python3'.pkgs; [ openssl mock pytestCheckHook responses testfixtures ]; - preCheck = "export HOME=$(mktemp -d)"; - postCheck = "unset HOME"; - disabledTests = [ - # expects `/home/` to exist, fails with `FileNotFoundError: [Errno 2] No such file or directory: '/home/'`. - "test_01_loading_scripts" - - # Tries to connect to `fcm.googleapis.com`. - "test_02_api_push_poll" - "test_04_decline_auth_request" - - # Timezone info not available in build sandbox - "test_14_convert_timestamp_to_utc" - - # Fails because of different logger configurations - "test_01_create_default_app" - "test_03_logging_config_file" - "test_04_logging_config_yaml" - "test_05_logging_config_broken_yaml" - ]; - - pythonImportsCheck = [ "privacyidea" ]; - - postPatch = '' - patchShebangs tests/testdata/scripts - substituteInPlace privacyidea/lib/resolvers/LDAPIdResolver.py --replace \ - "/etc/privacyidea/ldap-ca.crt" \ - "${cacert}/etc/ssl/certs/ca-bundle.crt" - ''; - - postInstall = '' - rm -r $out/${python3'.sitePackages}/tests - ''; - - meta = with lib; { - description = "Multi factor authentication system (2FA, MFA, OTP Server)"; - license = licenses.agpl3Plus; - homepage = "http://www.privacyidea.org"; - maintainers = with maintainers; [ ma27 ]; - platforms = platforms.linux; - }; -} diff --git a/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix b/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix deleted file mode 100644 index 0b2a85f7e94..00000000000 --- a/pkgs/development/python-modules/privacyidea-ldap-proxy/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ lib, buildPythonPackage, fetchFromGitHub, twisted, ldaptor, configobj, fetchpatch }: - -buildPythonPackage rec { - pname = "privacyidea-ldap-proxy"; - version = "0.7"; - - src = fetchFromGitHub { - owner = "privacyidea"; - repo = pname; - rev = "v${version}"; - sha256 = "1i2kgxqd38xvb42qj0a4a35w4vk0fyp3n7w48kqmvrxc77p6r6i8"; - }; - - patches = [ - # support for LDAPCompareRequest. - (fetchpatch { - url = "https://github.com/mayflower/privacyidea-ldap-proxy/commit/a13356717379b174f1a6abf767faa0dbd459f5dd.patch"; - hash = "sha256-SBTj9ayQ8JFD8BoYIl77nxWVV3PXnHZ8JMlJnxd/nEk="; - }) - ]; - - propagatedBuildInputs = [ twisted ldaptor configobj ]; - - pythonImportsCheck = [ "pi_ldapproxy" ]; - - meta = with lib; { - description = "LDAP Proxy to intercept LDAP binds and authenticate against privacyIDEA"; - homepage = "https://github.com/privacyidea/privacyidea-ldap-proxy"; - license = licenses.agpl3Only; - maintainers = [ ]; - }; -} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 85ac74fae7d..38c4126a20f 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -710,6 +710,7 @@ mapAliases ({ pinentry_qt = throw "'pinentry_qt' has been renamed to/replaced by 'pinentry-qt'"; # Converted to throw 2023-09-10 pinentry_qt5 = pinentry-qt; # Added 2020-02-11 poetry2nix = throw "poetry2nix is now maintained out-of-tree. Please use https://github.com/nix-community/poetry2nix/"; # Added 2023-10-26 + privacyidea = throw "privacyidea has been removed from nixpkgs"; # Added 2023-10-31 probe-rs-cli = throw "probe-rs-cli is now part of the probe-rs package"; # Added 2023-07-03 processing3 = throw "'processing3' has been renamed to/replaced by 'processing'"; # Converted to throw 2023-09-10 prometheus-dmarc-exporter = dmarc-metrics-exporter; # added 2022-05-31 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 77aaee8aa69..9d9a3a7a404 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -19871,8 +19871,6 @@ with pkgs; premake = premake4; - privacyidea = callPackage ../applications/misc/privacyidea { }; - process-compose = callPackage ../applications/misc/process-compose { }; process-viewer = callPackage ../applications/misc/process-viewer { }; diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix index f11511b81f9..5e273836060 100644 --- a/pkgs/top-level/python-aliases.nix +++ b/pkgs/top-level/python-aliases.nix @@ -262,7 +262,7 @@ mapAliases ({ poster3 = throw "poster3 is unmaintained and source is no longer available"; # added 2023-05-29 postorius = throw "Please use pkgs.mailmanPackages.postorius"; # added 2022-04-29 powerlineMemSegment = powerline-mem-segment; # added 2021-10-08 - privacyidea = throw "privacyidea has been renamed to pkgs.privacyidea"; # added 2021-06-20 + privacyidea-ldap-proxy = throw "privacyidea-ldap-proxy has been removed from nixpkgs"; # added 2023-10-31 prometheus_client = prometheus-client; # added 2021-06-10 prompt_toolkit = prompt-toolkit; # added 2021-07-22 protonup = protonup-ng; # Added 2022-11-06 diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index a71c3ed14ea..797fb18a26f 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -9510,8 +9510,6 @@ self: super: with self; { prison = callPackage ../development/python-modules/prison { }; - privacyidea-ldap-proxy = callPackage ../development/python-modules/privacyidea-ldap-proxy { }; - proboscis = callPackage ../development/python-modules/proboscis { }; process-tests = callPackage ../development/python-modules/process-tests { }; -- cgit 1.4.1 From b2fccae80913400dc6b63aa37c27a5c96243fcad Mon Sep 17 00:00:00 2001 From: Graham Bennett Date: Sat, 13 May 2023 22:42:00 +0100 Subject: zwave-js: module init, zwave-js-server: init at 1.33.0 Co-authored-by: Martin Weinelt Co-authored-by: h7x4 --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + .../modules/services/home-automation/zwave-js.nix | 152 ++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/zwave-js.nix | 31 ++++ pkgs/by-name/zw/zwave-js-server/package.nix | 36 ++++ pkgs/development/node-packages/aliases.nix | 1 + pkgs/development/node-packages/main-programs.nix | 1 - pkgs/development/node-packages/node-packages.json | 1 - pkgs/development/node-packages/node-packages.nix | 201 --------------------- 10 files changed, 224 insertions(+), 203 deletions(-) create mode 100644 nixos/modules/services/home-automation/zwave-js.nix create mode 100644 nixos/tests/zwave-js.nix create mode 100644 pkgs/by-name/zw/zwave-js-server/package.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index ffe977bf33b..eca3242cebb 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -104,6 +104,8 @@ - hardware/infiniband.nix adds infiniband subnet manager support using an [opensm](https://github.com/linux-rdma/opensm) systemd-template service, instantiated on card guids. The module also adds kernel modules and cli tooling to help administrators debug and measure performance. Available as [hardware.infiniband.enable](#opt-hardware.infiniband.enable). +- [zwave-js](https://github.com/zwave-js/zwave-js-server), a small server wrapper around Z-Wave JS to access it via a WebSocket. Available as [services.zwave-js](#opt-services.zwave-js.enable). + - [Honk](https://humungus.tedunangst.com/r/honk), a complete ActivityPub server with minimal setup and support costs. Available as [services.honk](#opt-services.honk.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2a6ca202024..f985de61445 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -563,6 +563,7 @@ ./services/home-automation/home-assistant.nix ./services/home-automation/homeassistant-satellite.nix ./services/home-automation/zigbee2mqtt.nix + ./services/home-automation/zwave-js.nix ./services/logging/SystemdJournal2Gelf.nix ./services/logging/awstats.nix ./services/logging/filebeat.nix diff --git a/nixos/modules/services/home-automation/zwave-js.nix b/nixos/modules/services/home-automation/zwave-js.nix new file mode 100644 index 00000000000..87c9b8f1ac8 --- /dev/null +++ b/nixos/modules/services/home-automation/zwave-js.nix @@ -0,0 +1,152 @@ +{config, pkgs, lib, ...}: + +with lib; + +let + cfg = config.services.zwave-js; + mergedConfigFile = "/run/zwave-js/config.json"; + settingsFormat = pkgs.formats.json {}; +in { + options.services.zwave-js = { + enable = mkEnableOption (mdDoc "the zwave-js server on boot"); + + package = mkPackageOptionMD pkgs "zwave-js-server" { }; + + port = mkOption { + type = types.port; + default = 3000; + description = mdDoc '' + Port for the server to listen on. + ''; + }; + + serialPort = mkOption { + type = types.path; + description = mdDoc '' + Serial port device path for Z-Wave controller. + ''; + example = "/dev/ttyUSB0"; + }; + + secretsConfigFile = mkOption { + type = types.path; + description = mdDoc '' + JSON file containing secret keys. A dummy example: + + ``` + { + "securityKeys": { + "S0_Legacy": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "S2_Unauthenticated": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", + "S2_Authenticated": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + "S2_AccessControl": "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" + } + } + ``` + + See + + for details. This file will be merged with the module-generated config + file (taking precedence). + + Z-Wave keys can be generated with: + + {command}`< /dev/urandom tr -dc A-F0-9 | head -c32 ;echo` + + + ::: {.warning} + A file in the nix store should not be used since it will be readable to + all users. + ::: + ''; + example = "/secrets/zwave-js-keys.json"; + }; + + settings = mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + + options = { + storage = { + cacheDir = mkOption { + type = types.path; + default = "/var/cache/zwave-js"; + readOnly = true; + description = lib.mdDoc "Cache directory"; + }; + }; + }; + }; + default = {}; + description = mdDoc '' + Configuration settings for the generated config + file. + ''; + }; + + extraFlags = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = [ "--mock-driver" ]; + description = lib.mdDoc '' + Extra flags to pass to command + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.zwave-js = let + configFile = settingsFormat.generate "zwave-js-config.json" cfg.settings; + in { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "Z-Wave JS Server"; + serviceConfig = { + ExecStartPre = '' + /bin/sh -c "${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configFile} ${cfg.secretsConfigFile} > ${mergedConfigFile}" + ''; + ExecStart = lib.concatStringsSep " " [ + "${cfg.package}/bin/zwave-server" + "--config ${mergedConfigFile}" + "--port ${toString cfg.port}" + cfg.serialPort + (escapeShellArgs cfg.extraFlags) + ]; + Restart = "on-failure"; + User = "zwave-js"; + SupplementaryGroups = [ "dialout" ]; + CacheDirectory = "zwave-js"; + RuntimeDirectory = "zwave-js"; + + # Hardening + CapabilityBoundingSet = ""; + DeviceAllow = [cfg.serialPort]; + DevicePolicy = "closed"; + DynamicUser = true; + LockPersonality = true; + MemoryDenyWriteExecute = false; + NoNewPrivileges = true; + PrivateUsers = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service @pkey" + "~@privileged @resources" + ]; + UMask = "0077"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ graham33 ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index f7f8ac8fec8..891dc714876 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -932,4 +932,5 @@ in { zram-generator = handleTest ./zram-generator.nix {}; zrepl = handleTest ./zrepl.nix {}; zsh-history = handleTest ./zsh-history.nix {}; + zwave-js = handleTest ./zwave-js.nix {}; } diff --git a/nixos/tests/zwave-js.nix b/nixos/tests/zwave-js.nix new file mode 100644 index 00000000000..9239e6964fd --- /dev/null +++ b/nixos/tests/zwave-js.nix @@ -0,0 +1,31 @@ +import ./make-test-python.nix ({ pkgs, lib, ...} : + +let + secretsConfigFile = pkgs.writeText "secrets.json" (builtins.toJSON { + securityKeys = { + "S0_Legacy" = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + }; + }); +in { + name = "zwave-js"; + meta.maintainers = with lib.maintainers; [ graham33 ]; + + nodes = { + machine = { config, ... }: { + services.zwave-js = { + enable = true; + serialPort = "/dev/null"; + extraFlags = ["--mock-driver"]; + inherit secretsConfigFile; + }; + }; + }; + + testScript = '' + start_all() + + machine.wait_for_unit("zwave-js.service") + machine.wait_for_open_port(3000) + machine.wait_until_succeeds("journalctl --since -1m --unit zwave-js --grep 'ZwaveJS server listening'") + ''; +}) diff --git a/pkgs/by-name/zw/zwave-js-server/package.nix b/pkgs/by-name/zw/zwave-js-server/package.nix new file mode 100644 index 00000000000..f97e16d6613 --- /dev/null +++ b/pkgs/by-name/zw/zwave-js-server/package.nix @@ -0,0 +1,36 @@ +{ lib +, buildNpmPackage +, fetchFromGitHub +, nixosTests +}: + +buildNpmPackage rec { + pname = "zwave-js-server"; + version = "1.33.0"; + + src = fetchFromGitHub { + owner = "zwave-js"; + repo = pname; + rev = version; + hash = "sha256-Lll3yE1v4ybJTjKO8dhPXMD/3VCn+9+fpnN7XczqaE4="; + }; + + npmDepsHash = "sha256-Re9fo+9+Z/+UGyDPlNWelH/4tLxcITPYXOCddQE9YDY="; + + # For some reason the zwave-js dependency is in devDependencies + npmFlags = [ "--include=dev" ]; + + passthru = { + tests = { + inherit (nixosTests) zwave-js; + }; + }; + + meta = { + changelog = "https://github.com/zwave-js/zwave-js-server/releases/tag/${version}"; + description = "Small server wrapper around Z-Wave JS to access it via a WebSocket"; + license = lib.licenses.asl20; + homepage = "https://github.com/zwave-js/zwave-js-server"; + maintainers = with lib.maintainers; [ graham33 ]; + }; +} diff --git a/pkgs/development/node-packages/aliases.nix b/pkgs/development/node-packages/aliases.nix index 3b4bf018e66..0bfe127efff 100644 --- a/pkgs/development/node-packages/aliases.nix +++ b/pkgs/development/node-packages/aliases.nix @@ -49,6 +49,7 @@ mapAliases { "@mermaid-js/mermaid-cli" = pkgs.mermaid-cli; # added 2023-10-01 "@nerdwallet/shepherd" = pkgs.shepherd; # added 2023-09-30 "@nestjs/cli" = pkgs.nest-cli; # Added 2023-05-06 + "@zwave-js/server" = pkgs.zwave-js-server; # Added 2023-09-09 alloy = pkgs.titanium-alloy; # added 2023-08-17 antennas = pkgs.antennas; # added 2023-07-30 inherit (pkgs) asar; # added 2023-08-26 diff --git a/pkgs/development/node-packages/main-programs.nix b/pkgs/development/node-packages/main-programs.nix index bd722955690..7b57757a07c 100644 --- a/pkgs/development/node-packages/main-programs.nix +++ b/pkgs/development/node-packages/main-programs.nix @@ -60,5 +60,4 @@ vscode-html-languageserver-bin = "html-languageserver"; vscode-json-languageserver-bin = "json-languageserver"; webtorrent-cli = "webtorrent"; - "@zwave-js/server" = "zwave-server"; } diff --git a/pkgs/development/node-packages/node-packages.json b/pkgs/development/node-packages/node-packages.json index f0e9b379f42..471b37c30bf 100644 --- a/pkgs/development/node-packages/node-packages.json +++ b/pkgs/development/node-packages/node-packages.json @@ -310,5 +310,4 @@ , "@yaegassy/coc-nginx" , "yalc" , "yarn" -, "@zwave-js/server" ] diff --git a/pkgs/development/node-packages/node-packages.nix b/pkgs/development/node-packages/node-packages.nix index 5f8eaa649d4..168d6b0c3c2 100644 --- a/pkgs/development/node-packages/node-packages.nix +++ b/pkgs/development/node-packages/node-packages.nix @@ -102095,205 +102095,4 @@ in bypassCache = true; reconstructLock = true; }; - "@zwave-js/server" = nodeEnv.buildNodePackage { - name = "_at_zwave-js_slash_server"; - packageName = "@zwave-js/server"; - version = "1.33.0"; - src = fetchurl { - url = "https://registry.npmjs.org/@zwave-js/server/-/server-1.33.0.tgz"; - sha512 = "jHRpbeWcDVhTWidDTmln9x+lTveJ0H1cLJxl6dWIeWQ6YnB7YzRuHFDPhY+6ewAyUrc+Eq8tl+QnhjmVuevq+A=="; - }; - dependencies = [ - (sources."@alcalzone/jsonl-db-3.1.0" // { - dependencies = [ - sources."fs-extra-10.1.0" - ]; - }) - (sources."@alcalzone/pak-0.9.0" // { - dependencies = [ - sources."execa-5.0.1" - sources."fs-extra-10.1.0" - ]; - }) - sources."@alcalzone/proper-lockfile-4.1.3-0" - sources."@colors/colors-1.6.0" - sources."@dabh/diagnostics-2.0.3" - sources."@homebridge/ciao-1.1.7" - sources."@leichtgewicht/ip-codec-2.0.4" - sources."@serialport/binding-mock-10.2.2" - (sources."@serialport/bindings-cpp-12.0.1" // { - dependencies = [ - sources."@serialport/parser-delimiter-11.0.0" - sources."@serialport/parser-readline-11.0.0" - sources."node-gyp-build-4.6.0" - ]; - }) - sources."@serialport/bindings-interface-1.2.2" - sources."@serialport/parser-byte-length-12.0.0" - sources."@serialport/parser-cctalk-12.0.0" - sources."@serialport/parser-delimiter-12.0.0" - sources."@serialport/parser-inter-byte-timeout-12.0.0" - sources."@serialport/parser-packet-length-12.0.0" - sources."@serialport/parser-readline-12.0.0" - sources."@serialport/parser-ready-12.0.0" - sources."@serialport/parser-regex-12.0.0" - sources."@serialport/parser-slip-encoder-12.0.0" - sources."@serialport/parser-spacepacket-12.0.0" - sources."@serialport/stream-12.0.0" - sources."@sindresorhus/is-5.6.0" - sources."@szmarczak/http-timer-5.0.1" - sources."@types/http-cache-semantics-4.0.3" - sources."@types/triple-beam-1.3.4" - sources."@zwave-js/cc-12.3.0" - sources."@zwave-js/config-12.3.0" - sources."@zwave-js/core-12.3.0" - sources."@zwave-js/host-12.3.0" - sources."@zwave-js/nvmedit-12.3.0" - sources."@zwave-js/serial-12.3.0" - sources."@zwave-js/shared-12.2.3" - sources."@zwave-js/testing-12.3.0" - sources."alcalzone-shared-4.0.8" - sources."ansi-colors-4.1.3" - sources."ansi-regex-5.0.1" - sources."ansi-styles-4.3.0" - sources."async-3.2.4" - sources."asynckit-0.4.0" - sources."axios-0.27.2" - sources."buffer-from-1.1.2" - sources."bufferutil-4.0.8" - sources."cacheable-lookup-7.0.0" - sources."cacheable-request-10.2.14" - sources."cliui-8.0.1" - (sources."color-3.2.1" // { - dependencies = [ - sources."color-convert-1.9.3" - sources."color-name-1.1.3" - ]; - }) - sources."color-convert-2.0.1" - sources."color-name-1.1.4" - sources."color-string-1.9.1" - sources."colorspace-1.1.4" - sources."combined-stream-1.0.8" - sources."cross-spawn-7.0.3" - sources."dayjs-1.11.10" - sources."debug-4.3.4" - (sources."decompress-response-6.0.0" // { - dependencies = [ - sources."mimic-response-3.1.0" - ]; - }) - sources."defer-to-connect-2.0.1" - sources."delayed-stream-1.0.0" - sources."dns-packet-5.6.1" - sources."emoji-regex-8.0.0" - sources."enabled-2.0.0" - sources."escalade-3.1.1" - sources."eventemitter3-5.0.1" - sources."execa-5.1.1" - sources."fast-deep-equal-3.1.3" - sources."fecha-4.2.3" - sources."file-stream-rotator-0.6.1" - sources."fn.name-1.1.0" - sources."follow-redirects-1.15.3" - sources."form-data-4.0.0" - sources."form-data-encoder-2.1.4" - sources."fs-extra-11.1.1" - sources."get-caller-file-2.0.5" - sources."get-stream-6.0.1" - sources."globalyzer-0.1.0" - sources."globrex-0.1.2" - sources."got-13.0.0" - sources."graceful-fs-4.2.11" - sources."http-cache-semantics-4.1.1" - sources."http2-wrapper-2.2.0" - sources."human-signals-2.1.0" - sources."inherits-2.0.4" - sources."is-arrayish-0.3.2" - sources."is-fullwidth-code-point-3.0.0" - sources."is-stream-2.0.1" - sources."isexe-2.0.0" - sources."json-buffer-3.0.1" - sources."json-logic-js-2.0.2" - sources."json5-2.2.3" - sources."jsonfile-6.1.0" - sources."keyv-4.5.4" - sources."kuler-2.0.0" - sources."logform-2.6.0" - sources."lowercase-keys-3.0.0" - sources."lru-cache-6.0.0" - sources."mdns-server-1.0.11" - sources."merge-stream-2.0.0" - sources."mime-db-1.52.0" - sources."mime-types-2.1.35" - sources."mimic-fn-2.1.0" - sources."mimic-response-4.0.0" - sources."minimist-1.2.8" - sources."moment-2.29.4" - sources."ms-2.1.2" - sources."node-addon-api-7.0.0" - sources."node-gyp-build-4.6.1" - sources."normalize-url-8.0.0" - sources."npm-run-path-4.0.1" - sources."nrf-intel-hex-1.3.0" - sources."object-hash-2.2.0" - sources."one-time-1.0.0" - sources."onetime-5.1.2" - sources."p-cancelable-3.0.0" - sources."p-queue-7.4.1" - sources."p-timeout-5.1.0" - sources."path-key-3.1.1" - sources."proper-lockfile-4.1.2" - sources."quick-lru-5.1.1" - sources."readable-stream-3.6.2" - sources."reflect-metadata-0.1.13" - sources."require-directory-2.1.1" - sources."resolve-alpn-1.2.1" - sources."responselike-3.0.0" - sources."retry-0.12.0" - sources."safe-buffer-5.2.1" - sources."safe-stable-stringify-2.4.3" - sources."semver-7.5.4" - sources."serialport-12.0.0" - sources."shebang-command-2.0.0" - sources."shebang-regex-3.0.0" - sources."signal-exit-3.0.7" - sources."simple-swizzle-0.2.2" - sources."source-map-0.6.1" - sources."source-map-support-0.5.21" - sources."stack-trace-0.0.10" - sources."string-width-4.2.3" - sources."string_decoder-1.3.0" - sources."strip-ansi-6.0.1" - sources."strip-final-newline-2.0.0" - sources."text-hex-1.0.0" - sources."tiny-glob-0.2.9" - sources."triple-beam-1.4.1" - sources."tslib-2.6.2" - sources."universalify-2.0.1" - sources."utf-8-validate-6.0.3" - sources."util-deprecate-1.0.2" - sources."which-2.0.2" - sources."winston-3.11.0" - sources."winston-daily-rotate-file-4.7.1" - sources."winston-transport-4.6.0" - sources."wrap-ansi-7.0.0" - sources."ws-8.14.2" - sources."xstate-4.38.2" - sources."y18n-5.0.8" - sources."yallist-4.0.0" - sources."yargs-17.7.2" - sources."yargs-parser-21.1.1" - sources."zwave-js-12.3.0" - ]; - buildInputs = globalBuildInputs; - meta = { - description = "Full access to zwave-js driver through Websockets"; - homepage = "https://github.com/zwave-js/zwave-js-server#readme"; - license = "Apache-2.0"; - }; - production = true; - bypassCache = true; - reconstructLock = true; - }; } -- cgit 1.4.1 From 1fff6a90316002764fee541e9ffa1bc7a9552521 Mon Sep 17 00:00:00 2001 From: Adam Stephens Date: Fri, 20 Oct 2023 00:10:59 -0400 Subject: nixos/incus: init module and tests --- nixos/modules/module-list.nix | 1 + nixos/modules/virtualisation/incus.nix | 232 ++++++++++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/incus/container.nix | 76 +++++++++ nixos/tests/incus/default.nix | 14 ++ nixos/tests/incus/preseed.nix | 65 ++++++++ nixos/tests/incus/socket-activated.nix | 25 +++ nixos/tests/incus/virtual-machine.nix | 55 +++++++ pkgs/by-name/co/cowsql/package.nix | 4 +- pkgs/by-name/in/incus-unwrapped/package.nix | 3 + pkgs/by-name/in/incus/package.nix | 2 + pkgs/by-name/ra/raft-cowsql/package.nix | 9 +- 12 files changed, 481 insertions(+), 6 deletions(-) create mode 100644 nixos/modules/virtualisation/incus.nix create mode 100644 nixos/tests/incus/container.nix create mode 100644 nixos/tests/incus/default.nix create mode 100644 nixos/tests/incus/preseed.nix create mode 100644 nixos/tests/incus/socket-activated.nix create mode 100644 nixos/tests/incus/virtual-machine.nix (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index bfac651f5a8..55c74bc327d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1506,6 +1506,7 @@ ./virtualisation/docker.nix ./virtualisation/ecs-agent.nix ./virtualisation/hyperv-guest.nix + ./virtualisation/incus.nix ./virtualisation/kvmgt.nix ./virtualisation/libvirtd.nix ./virtualisation/lxc.nix diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix new file mode 100644 index 00000000000..d7ccc963f6a --- /dev/null +++ b/nixos/modules/virtualisation/incus.nix @@ -0,0 +1,232 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.virtualisation.incus; + preseedFormat = pkgs.formats.yaml { }; +in +{ + meta.maintainers = [ lib.maintainers.adamcstephens ]; + + options = { + virtualisation.incus = { + enable = lib.mkEnableOption (lib.mdDoc '' + 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.mkPackageOptionMD pkgs "incus" { }; + + lxcPackage = lib.mkPackageOptionMD pkgs "lxc" { }; + + preseed = lib.mkOption { + type = lib.types.nullOr ( + lib.types.submodule { freeformType = preseedFormat.type; } + ); + + default = null; + + description = lib.mdDoc '' + Configuration for Incus preseed, see + + for supported values. + + Changes to this will be re-applied to Incus which will overwrite existing entities or create missing ones, + but entities will *not* be removed by preseed. + ''; + + example = { + networks = [ + { + name = "incusbr0"; + type = "bridge"; + config = { + "ipv4.address" = "10.0.100.1/24"; + "ipv4.nat" = "true"; + }; + } + ]; + profiles = [ + { + name = "default"; + devices = { + eth0 = { + name = "eth0"; + network = "incusbr0"; + type = "nic"; + }; + root = { + path = "/"; + pool = "default"; + size = "35GiB"; + type = "disk"; + }; + }; + } + ]; + storage_pools = [ + { + name = "default"; + driver = "dir"; + config = { + source = "/var/lib/incus/storage-pools/default"; + }; + } + ]; + }; + }; + + socketActivation = lib.mkEnableOption ( + lib.mdDoc '' + 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 '' + 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. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + # https://github.com/lxc/incus/blob/f145309929f849b9951658ad2ba3b8f10cbe69d1/doc/reference/server_settings.md + boot.kernel.sysctl = { + "fs.aio-max-nr" = lib.mkDefault 524288; + "fs.inotify.max_queued_events" = lib.mkDefault 1048576; + "fs.inotify.max_user_instances" = lib.mkOverride 1050 1048576; # override in case conflict nixos/modules/services/x11/xserver.nix + "fs.inotify.max_user_watches" = lib.mkOverride 1050 1048576; # override in case conflict nixos/modules/services/x11/xserver.nix + "kernel.dmesg_restrict" = lib.mkDefault 1; + "kernel.keys.maxbytes" = lib.mkDefault 2000000; + "kernel.keys.maxkeys" = lib.mkDefault 2000; + "net.core.bpf_jit_limit" = lib.mkDefault 1000000000; + "net.ipv4.neigh.default.gc_thresh3" = lib.mkDefault 8192; + "net.ipv6.neigh.default.gc_thresh3" = lib.mkDefault 8192; + # vm.max_map_count is set higher in nixos/modules/config/sysctl.nix + }; + + boot.kernelModules = [ + "veth" + "xt_comment" + "xt_CHECKSUM" + "xt_MASQUERADE" + "vhost_vsock" + ] ++ lib.optionals (!config.networking.nftables.enable) [ "iptable_mangle" ]; + + environment.systemPackages = [ cfg.package ]; + + # Note: the following options are also declared in virtualisation.lxc, but + # the latter can't be simply enabled to reuse the formers, because it + # does a bunch of unrelated things. + systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ]; + + security.apparmor = { + packages = [ cfg.lxcPackage ]; + policies = { + "bin.lxc-start".profile = '' + include ${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start + ''; + "lxc-containers".profile = '' + include ${cfg.lxcPackage}/etc/apparmor.d/lxc-containers + ''; + }; + }; + + systemd.services.incus = { + description = "Incus Container and Virtual Machine Management Daemon"; + + wantedBy = lib.mkIf (!cfg.socketActivation) [ "multi-user.target" ]; + after = [ + "network-online.target" + "lxcfs.service" + ] ++ (lib.optional cfg.socketActivation "incus.socket"); + requires = [ + "lxcfs.service" + ] ++ (lib.optional cfg.socketActivation "incus.socket"); + wants = [ + "network-online.target" + ]; + + path = lib.mkIf config.boot.zfs.enabled [ config.boot.zfs.package ]; + + environment = { + # Override Path to the LXC template configuration directory + INCUS_LXC_TEMPLATE_CONFIG = "${pkgs.lxcfs}/share/lxc/config"; + }; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/incusd --group incus-admin"; + ExecStartPost = "${cfg.package}/bin/incusd waitready --timeout=${cfg.startTimeout}"; + + KillMode = "process"; # when stopping, leave the containers alone + Delegate = "yes"; + LimitMEMLOCK = "infinity"; + LimitNOFILE = "1048576"; + LimitNPROC = "infinity"; + TasksMax = "infinity"; + + Restart = "on-failure"; + TimeoutStartSec = "${cfg.startTimeout}s"; + TimeoutStopSec = "30s"; + }; + }; + + systemd.sockets.incus = lib.mkIf cfg.socketActivation { + description = "Incus UNIX socket"; + wantedBy = [ "sockets.target" ]; + + socketConfig = { + ListenStream = "/var/lib/incus/unix.socket"; + SocketMode = "0660"; + SocketGroup = "incus-admin"; + Service = "incus.service"; + }; + }; + + systemd.services.incus-preseed = lib.mkIf (cfg.preseed != null) { + description = "Incus initialization with preseed file"; + wantedBy = [ "multi-user.target" ]; + requires = [ "incus.service" ]; + after = [ "incus.service" ]; + + script = '' + ${cfg.package}/bin/incus admin init --preseed <${ + preseedFormat.generate "incus-preseed.yaml" cfg.preseed + } + ''; + + serviceConfig = { + Type = "oneshot"; + }; + }; + + users.groups.incus-admin = { }; + + users.users.root = { + # match documented default ranges https://linuxcontainers.org/incus/docs/main/userns-idmap/#allowed-ranges + subUidRanges = [ + { + startUid = 1000000; + count = 1000000000; + } + ]; + subGidRanges = [ + { + startGid = 1000000; + count = 1000000000; + } + ]; + }; + + virtualisation.lxc.lxcfs.enable = true; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 2f6d5a8dae8..69549c8d534 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -392,6 +392,7 @@ in { icingaweb2 = handleTest ./icingaweb2.nix {}; iftop = handleTest ./iftop.nix {}; incron = handleTest ./incron.nix {}; + incus = pkgs.recurseIntoAttrs (handleTest ./incus { inherit handleTestOn; }); influxdb = handleTest ./influxdb.nix {}; influxdb2 = handleTest ./influxdb2.nix {}; initrd-network-openvpn = handleTest ./initrd-network-openvpn {}; diff --git a/nixos/tests/incus/container.nix b/nixos/tests/incus/container.nix new file mode 100644 index 00000000000..ce9a8a10fb2 --- /dev/null +++ b/nixos/tests/incus/container.nix @@ -0,0 +1,76 @@ +import ../make-test-python.nix ({ pkgs, lib, ... } : + +let + releases = import ../../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; + }; + }; + + container-image-metadata = releases.lxdContainerMeta.${pkgs.stdenv.hostPlatform.system}; + container-image-rootfs = releases.lxdContainerImage.${pkgs.stdenv.hostPlatform.system}; +in +{ + name = "incus-container"; + + meta.maintainers = with lib.maintainers; [ adamcstephens ]; + + nodes.machine = { ... }: { + virtualisation = { + # Ensure test VM has enough resources for creating and managing guests + cores = 2; + memorySize = 1024; + diskSize = 4096; + + incus.enable = true; + }; + }; + + testScript = '' + def instance_is_up(_) -> bool: + status, _ = machine.execute("incus exec container --disable-stdin --force-interactive /run/current-system/sw/bin/true") + return status == 0 + + machine.wait_for_unit("incus.service") + + # no preseed should mean no service + machine.fail("systemctl status incus-preseed.service") + + machine.succeed("incus admin init --minimal") + + with subtest("Container image can be imported"): + machine.succeed("incus image import ${container-image-metadata}/*/*.tar.xz ${container-image-rootfs}/*/*.tar.xz --alias nixos") + + with subtest("Container can be launched and managed"): + machine.succeed("incus launch nixos container") + with machine.nested("Waiting for instance to start and be usable"): + retry(instance_is_up) + machine.succeed("echo true | incus exec container /run/current-system/sw/bin/bash -") + + with subtest("Container CPU limits can be managed"): + machine.succeed("incus config set container limits.cpu 1") + # give container a chance to apply new resource limit + machine.sleep(1) + cpuinfo = machine.succeed("incus exec container grep -- -c ^processor /proc/cpuinfo").strip() + assert cpuinfo == "1", f"Wrong number of CPUs reported from /proc/cpuinfo, want: 1, got: {cpuinfo}" + + machine.succeed("incus config set container limits.cpu 2") + machine.sleep(1) + cpuinfo = machine.succeed("incus exec container grep -- -c ^processor /proc/cpuinfo").strip() + assert cpuinfo == "2", f"Wrong number of CPUs reported from /proc/cpuinfo, want: 2, got: {cpuinfo}" + + with subtest("Container memory limits can be managed"): + machine.succeed("incus config set container limits.memory 64MB") + machine.sleep(1) + meminfo = machine.succeed("incus exec container grep -- MemTotal /proc/meminfo").strip() + meminfo_bytes = " ".join(meminfo.split(' ')[-2:]) + assert meminfo_bytes == "62500 kB", f"Wrong amount of memory reported from /proc/meminfo, want: '62500 kB', got: '{meminfo_bytes}'" + + machine.succeed("incus config set container limits.memory 128MB") + machine.sleep(1) + meminfo = machine.succeed("incus exec container grep -- MemTotal /proc/meminfo").strip() + meminfo_bytes = " ".join(meminfo.split(' ')[-2:]) + assert meminfo_bytes == "125000 kB", f"Wrong amount of memory reported from /proc/meminfo, want: '62500 kB', got: '{meminfo_bytes}'" + ''; +}) diff --git a/nixos/tests/incus/default.nix b/nixos/tests/incus/default.nix new file mode 100644 index 00000000000..c88974605e3 --- /dev/null +++ b/nixos/tests/incus/default.nix @@ -0,0 +1,14 @@ +{ + system ? builtins.currentSystem, + config ? { }, + pkgs ? import ../../.. { inherit system config; }, + handleTestOn, +}: +{ + container = import ./container.nix { inherit system pkgs; }; + preseed = import ./preseed.nix { inherit system pkgs; }; + socket-activated = import ./socket-activated.nix { inherit system pkgs; }; + virtual-machine = handleTestOn [ "x86_64-linux" ] ./virtual-machine.nix { + inherit system pkgs; + }; +} diff --git a/nixos/tests/incus/preseed.nix b/nixos/tests/incus/preseed.nix new file mode 100644 index 00000000000..19ec3889093 --- /dev/null +++ b/nixos/tests/incus/preseed.nix @@ -0,0 +1,65 @@ +import ../make-test-python.nix ({ pkgs, lib, ... } : + +{ + name = "incus-preseed"; + + meta.maintainers = with lib.maintainers; [ adamcstephens ]; + + nodes.machine = { lib, ... }: { + virtualisation = { + incus.enable = true; + + incus.preseed = { + networks = [ + { + name = "nixostestbr0"; + type = "bridge"; + config = { + "ipv4.address" = "10.0.100.1/24"; + "ipv4.nat" = "true"; + }; + } + ]; + profiles = [ + { + name = "nixostest_default"; + devices = { + eth0 = { + name = "eth0"; + network = "nixostestbr0"; + type = "nic"; + }; + root = { + path = "/"; + pool = "default"; + size = "35GiB"; + type = "disk"; + }; + }; + } + ]; + storage_pools = [ + { + name = "nixostest_pool"; + driver = "dir"; + } + ]; + }; + }; + }; + + testScript = '' + def wait_for_preseed(_) -> bool: + _, output = machine.systemctl("is-active incus-preseed.service") + return ("inactive" in output) + + machine.wait_for_unit("incus.service") + with machine.nested("Waiting for preseed to complete"): + retry(wait_for_preseed) + + with subtest("Verify preseed resources created"): + machine.succeed("incus profile show nixostest_default") + machine.succeed("incus network info nixostestbr0") + machine.succeed("incus storage show nixostest_pool") + ''; +}) diff --git a/nixos/tests/incus/socket-activated.nix b/nixos/tests/incus/socket-activated.nix new file mode 100644 index 00000000000..e48831cd3cb --- /dev/null +++ b/nixos/tests/incus/socket-activated.nix @@ -0,0 +1,25 @@ +import ../make-test-python.nix ({ pkgs, lib, ... } : + +{ + name = "incus-socket-activated"; + + meta.maintainers = with lib.maintainers; [ adamcstephens ]; + + nodes.machine = { lib, ... }: { + virtualisation = { + incus.enable = true; + incus.socketActivation = true; + }; + }; + + testScript = '' + machine.wait_for_unit("incus.socket") + + # ensure service is not running by default + machine.fail("systemctl is-active incus.service") + + # access the socket and ensure the service starts + machine.succeed("incus list") + machine.wait_for_unit("incus.service") + ''; +}) diff --git a/nixos/tests/incus/virtual-machine.nix b/nixos/tests/incus/virtual-machine.nix new file mode 100644 index 00000000000..bfa116679d4 --- /dev/null +++ b/nixos/tests/incus/virtual-machine.nix @@ -0,0 +1,55 @@ +import ../make-test-python.nix ({ pkgs, lib, ... }: + +let + releases = import ../../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; + + # Our tests require `grep` & friends: + environment.systemPackages = with pkgs; [busybox]; + }; + }; + + vm-image-metadata = releases.lxdVirtualMachineImageMeta.${pkgs.stdenv.hostPlatform.system}; + vm-image-disk = releases.lxdVirtualMachineImage.${pkgs.stdenv.hostPlatform.system}; + + instance-name = "instance1"; +in +{ + name = "incus-virtual-machine"; + + meta.maintainers = with lib.maintainers; [ adamcstephens ]; + + nodes.machine = {...}: { + virtualisation = { + # Ensure test VM has enough resources for creating and managing guests + cores = 2; + memorySize = 1024; + diskSize = 4096; + + incus.enable = true; + }; + }; + + testScript = '' + def instance_is_up(_) -> bool: + status, _ = machine.execute("incus exec ${instance-name} --disable-stdin --force-interactive /run/current-system/sw/bin/true") + return status == 0 + + machine.wait_for_unit("incus.service") + + machine.succeed("incus admin init --minimal") + + with subtest("virtual-machine image can be imported"): + machine.succeed("incus image import ${vm-image-metadata}/*/*.tar.xz ${vm-image-disk}/nixos.qcow2 --alias nixos") + + with subtest("virtual-machine can be launched and become available"): + machine.succeed("incus launch nixos ${instance-name} --vm --config limits.memory=512MB --config security.secureboot=false") + with machine.nested("Waiting for instance to start and be usable"): + retry(instance_is_up) + + with subtest("lxd-agent is started"): + machine.succeed("incus exec ${instance-name} systemctl is-active lxd-agent") + ''; +}) diff --git a/pkgs/by-name/co/cowsql/package.nix b/pkgs/by-name/co/cowsql/package.nix index c7b7b97e979..e0ce2660912 100644 --- a/pkgs/by-name/co/cowsql/package.nix +++ b/pkgs/by-name/co/cowsql/package.nix @@ -39,9 +39,7 @@ stdenv.mkDerivation (finalAttrs: { outputs = [ "dev" "out" ]; passthru = { - tests = { - inherit incus; - }; + inherit (incus) tests; updateScript = gitUpdater { rev-prefix = "v"; diff --git a/pkgs/by-name/in/incus-unwrapped/package.nix b/pkgs/by-name/in/incus-unwrapped/package.nix index 051527357ca..4c256481bfc 100644 --- a/pkgs/by-name/in/incus-unwrapped/package.nix +++ b/pkgs/by-name/in/incus-unwrapped/package.nix @@ -11,6 +11,7 @@ , udev , installShellFiles , nix-update-script +, nixosTests }: buildGoModule rec { @@ -79,6 +80,8 @@ buildGoModule rec { ''; passthru = { + tests.incus = nixosTests.incus; + updateScript = nix-update-script { extraArgs = [ "-vr" "incus-\(.*\)" diff --git a/pkgs/by-name/in/incus/package.nix b/pkgs/by-name/in/incus/package.nix index 1eda9cf3ea7..e02876407a7 100644 --- a/pkgs/by-name/in/incus/package.nix +++ b/pkgs/by-name/in/incus/package.nix @@ -24,6 +24,7 @@ , rsync , spice-gtk , squashfsTools +, util-linux , virtiofsd , xz }: @@ -44,6 +45,7 @@ let qemu-utils rsync squashfsTools + util-linux virtiofsd xz diff --git a/pkgs/by-name/ra/raft-cowsql/package.nix b/pkgs/by-name/ra/raft-cowsql/package.nix index 821abd91727..a377f966241 100644 --- a/pkgs/by-name/ra/raft-cowsql/package.nix +++ b/pkgs/by-name/ra/raft-cowsql/package.nix @@ -41,9 +41,12 @@ stdenv.mkDerivation rec { outputs = [ "dev" "out" ]; - passthru.tests = { - inherit incus; - updateScript = gitUpdater { }; + passthru = { + inherit (incus) tests; + + updateScript = gitUpdater { + rev-prefix = "v"; + }; }; meta = with lib; { -- cgit 1.4.1 From 3ce4c661512bb86209fbce9ffda0a356e86b4822 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 4 Nov 2023 01:02:27 +0300 Subject: nixos/module-list: add virt-manager Was missed in #261474 --- nixos/modules/module-list.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 9a1bc0450d2..44acc011ba1 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -267,6 +267,7 @@ ./programs/udevil.nix ./programs/usbtop.nix ./programs/vim.nix + ./programs/virt-manager.nix ./programs/wavemon.nix ./programs/wayland/cardboard.nix ./programs/wayland/river.nix -- cgit 1.4.1 From 40c06a143fc487b93987740454bf0af646f9c2d4 Mon Sep 17 00:00:00 2001 From: tu-maurice Date: Thu, 9 Nov 2023 22:27:23 +0100 Subject: prayer: remove --- nixos/doc/manual/release-notes/rl-2311.section.md | 2 + nixos/modules/misc/ids.nix | 4 +- nixos/modules/module-list.nix | 1 - nixos/modules/rename.nix | 1 + nixos/modules/services/networking/prayer.nix | 90 ------------ pkgs/servers/prayer/default.nix | 56 ------- pkgs/servers/prayer/install.patch | 170 ---------------------- pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 2 - 9 files changed, 6 insertions(+), 321 deletions(-) delete mode 100644 nixos/modules/services/networking/prayer.nix delete mode 100644 pkgs/servers/prayer/default.nix delete mode 100644 pkgs/servers/prayer/install.patch (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 7a1dfd49c4f..d838d33e35d 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -363,6 +363,8 @@ - The `junicode` font package has been updated to [major version 2](https://github.com/psb1558/Junicode-font/releases/tag/v2.001), which is now a font family. In particular, plain `Junicode.ttf` no longer exists. In addition, TrueType font files are now placed in `font/truetype` instead of `font/junicode-ttf`; this change does not affect use via `fonts.packages` NixOS option. +- The `prayer` package as well as `services.prayer` have been removed because it's been unmaintained for several years and the author's website has vanished. + ## Other Notable Changes {#sec-release-23.11-notable-changes} - A new option `system.switch.enable` was added. By default, this is option is diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 5b278b5e806..18928a6bf21 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -86,7 +86,7 @@ in #rtkit = 45; # dynamically allocated 2021-09-03 dovecot2 = 46; dovenull2 = 47; - prayer = 49; + # prayer = 49; # dropped in 23.11 mpd = 50; clamav = 51; #fprot = 52; # unused @@ -411,7 +411,7 @@ in #rtkit = 45; # unused dovecot2 = 46; dovenull2 = 47; - prayer = 49; + # prayer = 49; # dropped in 23.11 mpd = 50; clamav = 51; #fprot = 52; # unused diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6679e5bb7c6..00da6399295 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1041,7 +1041,6 @@ ./services/networking/powerdns.nix ./services/networking/pppd.nix ./services/networking/pptpd.nix - ./services/networking/prayer.nix ./services/networking/privoxy.nix ./services/networking/prosody.nix ./services/networking/quassel.nix diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 0fbb2351f98..3fab863adb7 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -111,6 +111,7 @@ in (mkRemovedOptionModule [ "services" "riak" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "cryptpad" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "rtsp-simple-server" ] "Package has been completely rebranded by upstream as mediamtx, and thus the service and the package were renamed in NixOS as well.") + (mkRemovedOptionModule [ "services" "prayer" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx" ] "The fcitx module has been removed. Please use fcitx5 instead") (mkRemovedOptionModule [ "services" "dhcpd4" ] '' diff --git a/nixos/modules/services/networking/prayer.nix b/nixos/modules/services/networking/prayer.nix deleted file mode 100644 index 197aa8a6f44..00000000000 --- a/nixos/modules/services/networking/prayer.nix +++ /dev/null @@ -1,90 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - inherit (pkgs) prayer; - - cfg = config.services.prayer; - - stateDir = "/var/lib/prayer"; - - prayerUser = "prayer"; - prayerGroup = "prayer"; - - prayerExtraCfg = pkgs.writeText "extraprayer.cf" '' - prefix = "${prayer}" - var_prefix = "${stateDir}" - prayer_user = "${prayerUser}" - prayer_group = "${prayerGroup}" - sendmail_path = "/run/wrappers/bin/sendmail" - - use_http_port ${cfg.port} - - ${cfg.extraConfig} - ''; - - prayerCfg = pkgs.runCommand "prayer.cf" { preferLocalBuild = true; } '' - # We have to remove the http_port 80, or it will start a server there - cat ${prayer}/etc/prayer.cf | grep -v http_port > $out - cat ${prayerExtraCfg} >> $out - ''; - -in - -{ - - ###### interface - - options = { - - services.prayer = { - - enable = mkEnableOption (lib.mdDoc "the prayer webmail http server"); - - port = mkOption { - default = 2080; - type = types.port; - description = lib.mdDoc '' - Port the prayer http server is listening to. - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = "" ; - description = lib.mdDoc '' - Extra configuration. Contents will be added verbatim to the configuration file. - ''; - }; - }; - - }; - - - ###### implementation - - config = mkIf config.services.prayer.enable { - environment.systemPackages = [ prayer ]; - - users.users.${prayerUser} = - { uid = config.ids.uids.prayer; - description = "Prayer daemon user"; - home = stateDir; - }; - - users.groups.${prayerGroup} = - { gid = config.ids.gids.prayer; }; - - systemd.services.prayer = { - wantedBy = [ "multi-user.target" ]; - serviceConfig.Type = "forking"; - preStart = '' - mkdir -m 0755 -p ${stateDir} - chown ${prayerUser}:${prayerGroup} ${stateDir} - ''; - script = "${prayer}/sbin/prayer --config-file=${prayerCfg}"; - }; - }; -} diff --git a/pkgs/servers/prayer/default.nix b/pkgs/servers/prayer/default.nix deleted file mode 100644 index c335358b6dd..00000000000 --- a/pkgs/servers/prayer/default.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ lib, stdenv, fetchurl, fetchpatch, perl, openssl, db, zlib, uwimap, html-tidy, pam}: - -let - ssl = lib.optionals uwimap.withSSL - "-e 's/CCLIENT_SSL_ENABLE.*= false/CCLIENT_SSL_ENABLE=true/'"; -in -stdenv.mkDerivation rec { - pname = "prayer"; - version = "1.3.5"; - - src = fetchurl { - url = "ftp://ftp.csx.cam.ac.uk/pub/software/email/prayer/${pname}-${version}.tar.gz"; - sha256 = "135fjbxjn385b6cjys6qhbwfw61mdcl2akkll4jfpdzfvhbxlyda"; - }; - - patches = [ - ./install.patch - - # fix build errors which result from openssl changes - (fetchpatch { - url = "https://sources.debian.org/data/main/p/prayer/1.3.5-dfsg1-6/debian/patches/disable_ssl3.patch"; - sha256 = "1rx4bidc9prh4gffipykp144cyi3zd6qzd990s2aad3knzv5bkdd"; - }) - (fetchpatch { - url = "https://sources.debian.org/data/main/p/prayer/1.3.5-dfsg1-6/debian/patches/openssl1.1.patch"; - sha256 = "0zinylvq3bcifdmki867gir49pbjx6qb5h019hawwif2l4jmlxw1"; - }) - ]; - - postPatch = '' - sed -i -e s/gmake/make/ -e 's/LDAP_ENABLE.*= true/LDAP_ENABLE=false/' \ - ${ssl} \ - -e 's/CCLIENT_LIBS=.*/CCLIENT_LIBS=-lc-client/' \ - -e 's,^PREFIX .*,PREFIX='$out, \ - -e 's,^CCLIENT_DIR=.*,CCLIENT_DIR=${uwimap}/include/c-client,' \ - Config - sed -i -e s,/usr/bin/perl,${perl}/bin/perl, \ - templates/src/*.pl - sed -i -e '//d' lib/os_linux.h - '' + /* html-tidy updates */ '' - substituteInPlace ./session/html_secure_tidy.c \ - --replace buffio.h tidybuffio.h - ''; - - buildInputs = [ openssl db zlib uwimap html-tidy pam ]; - nativeBuildInputs = [ perl ]; - - NIX_LDFLAGS = "-lpam"; - - meta = { - homepage = "http://www-uxsup.csx.cam.ac.uk/~dpc22/prayer/"; - description = "Yet another Webmail interface for IMAP servers on Unix systems written in C"; - license = lib.licenses.gpl2Plus; - platforms = lib.platforms.linux; - }; -} diff --git a/pkgs/servers/prayer/install.patch b/pkgs/servers/prayer/install.patch deleted file mode 100644 index 439202dd955..00000000000 --- a/pkgs/servers/prayer/install.patch +++ /dev/null @@ -1,170 +0,0 @@ -diff --git a/accountd/Makefile b/accountd/Makefile -index c3e8107..7946776 100644 ---- a/accountd/Makefile -+++ b/accountd/Makefile -@@ -75,6 +75,6 @@ clean: - -rm -f prayer-accountd test core *.o *~ \#*\# - - install: -- $(INSTALL) -m 755 -o ${RO_USER} -g ${RW_GROUP} \ -+ $(INSTALL) -m 755 \ - prayer-accountd ${BROOT}${BIN_DIR} - -diff --git a/files/Makefile b/files/Makefile -index 743d0ed..7eff064 100644 ---- a/files/Makefile -+++ b/files/Makefile -@@ -52,20 +52,20 @@ distclean: - - install-cert: - if [ -f certs/prayer.pem ]; then \ -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) \ -+ $(INSTALL) \ - -m $(PRIVATE_FILE) certs/prayer.pem ${BROOT}${PREFIX}/certs; \ - fi - - install-config: etc/prayer.cf -- $(INSTALL) -D -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_FILE) \ -+ $(INSTALL) -D -m $(PUBLIC_FILE) \ - etc/prayer.cf ${BROOT}${PRAYER_CONFIG_FILE} - - install-aconfig: -- $(INSTALL) -D -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_FILE) \ -+ $(INSTALL) -D -m $(PUBLIC_FILE) \ - etc/prayer-accountd.cf ${BROOT}${ACCOUNTD_CONFIG_FILE} - - install-motd: -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_FILE) \ -+ $(INSTALL) -m $(PUBLIC_FILE) \ - etc/motd.html ${BROOT}${PREFIX}/etc - - install: -@@ -83,6 +83,6 @@ install: - if [ ! -f $(BROOT)$(PREFIX)/etc/motd.html ]; then $(MAKE) install-motd; fi - - redhat-install-init.d: -- install -D -o root -g root -m 755 \ -+ install -D -m 755 \ - ./init.d/prayer $(BROOT)/etc/rc.d/init.d/prayer - #chkconfig prayer --level 2345 on -diff --git a/files/install.sh b/files/install.sh -index 8d1d1f4..0804a08 100755 ---- a/files/install.sh -+++ b/files/install.sh -@@ -2,8 +2,6 @@ - # - # $Cambridge: hermes/src/prayer/files/install.sh,v 1.7 2008/09/16 09:59:56 dpc22 Exp $ - --PATH=/bin:/sbin/:/usr/bin:/usr/sbin -- - error=0 - - if [ "x$PREFIX" = "x" ]; then -@@ -55,24 +53,20 @@ if [ $error != 0 ]; then - exit 1 - fi - --if [ ! -d ${VAR_PREFIX} -a `whoami` = "root" ]; then -- ${INSTALL} -d -o ${RW_USER} -g ${RW_GROUP} -m ${PRIVATE_DIR} ${VAR_PREFIX} --fi -- - if [ ! -d ${PREFIX} ]; then -- ${INSTALL} -d -o ${RO_USER} -g ${RO_GROUP} -m ${PUBLIC_DIR} ${PREFIX} -+ ${INSTALL} -d -m ${PUBLIC_DIR} ${PREFIX} - fi - - if [ ! -d ${PREFIX}/etc ]; then -- ${INSTALL} -d -o ${RO_USER} -g ${RO_GROUP} -m ${PUBLIC_DIR} ${PREFIX}/etc -+ ${INSTALL} -d -m ${PUBLIC_DIR} ${PREFIX}/etc - fi - - if [ ! -d ${PREFIX}/certs ]; then -- ${INSTALL} -d -o ${RO_USER} -g ${RO_GROUP} -m ${PRIVATE_DIR} ${PREFIX}/certs -+ ${INSTALL} -d -m ${PRIVATE_DIR} ${PREFIX}/certs - fi - - if [ ! -d ${BIN_DIR} ]; then -- ${INSTALL} -d -o ${RO_USER} -g ${RO_GROUP} -m ${PUBLIC_DIR} ${BIN_DIR} -+ ${INSTALL} -d -m ${PUBLIC_DIR} ${BIN_DIR} - fi - - for i in icons static -@@ -83,5 +77,4 @@ do - fi - echo Copying ${i} - (tar cf - ${i}) | (cd ${PREFIX} ; tar xf -) -- (cd ${PREFIX}; chown -R ${RO_USER}:${RO_GROUP} ${i}) - done -diff --git a/servers/Makefile b/servers/Makefile -index 021aed5..5ccbd08 100644 ---- a/servers/Makefile -+++ b/servers/Makefile -@@ -107,13 +107,13 @@ clean: - -rm -f $(BIN) core *.o *.flc *~ \#*\# - - install: all -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_DIR) -d \ -+ $(INSTALL) -m $(PUBLIC_DIR) -d \ - $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-chroot $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-session $(BROOT)$(BIN_DIR) - - prayer: $(PRAYER_OBJS) prayer_main.o -diff --git a/templates/cam/Makefile b/templates/cam/Makefile -index 9f4122a..396b628 100644 ---- a/templates/cam/Makefile -+++ b/templates/cam/Makefile -@@ -124,7 +124,7 @@ _template_index.c: - $(COMPILE) $(TYPE) $@ $* - - install: -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_DIR) -d \ -+ $(INSTALL) -m $(PUBLIC_DIR) -d \ - $(BROOT)$(PREFIX)/templates/$(TYPE) - cp *.t $(BROOT)$(PREFIX)/templates/$(TYPE) - cp *.vars $(BROOT)$(PREFIX)/templates/$(TYPE) -diff --git a/templates/old/Makefile b/templates/old/Makefile -index 31016cf..288a64c 100644 ---- a/templates/old/Makefile -+++ b/templates/old/Makefile -@@ -123,7 +123,7 @@ _template_index.c: - $(COMPILE) $(TYPE) $@ $* - - install: -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_DIR) -d \ -+ $(INSTALL) -m $(PUBLIC_DIR) -d \ - $(BROOT)$(PREFIX)/templates/$(TYPE) - cp *.t $(BROOT)$(PREFIX)/templates/$(TYPE) - cp *.vars $(BROOT)$(PREFIX)/templates/$(TYPE) -diff --git a/utils/Makefile b/utils/Makefile -index 9c79916..ef82481 100644 ---- a/utils/Makefile -+++ b/utils/Makefile -@@ -72,15 +72,15 @@ clean: - -rm -f $(BIN) core *.o *.flc *~ \#*\# - - install: all -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_DIR) -d \ -+ $(INSTALL) -m $(PUBLIC_DIR) -d \ - $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-ssl-prune $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-sem-prune $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-db-prune $(BROOT)$(BIN_DIR) -- $(INSTALL) -o $(RO_USER) -g $(RO_GROUP) -m $(PUBLIC_EXEC) \ -+ $(INSTALL) -m $(PUBLIC_EXEC) \ - prayer-cyclog $(BROOT)$(BIN_DIR) - - prayer-ssl-prune: $(PRUNE_OBJS) diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 1a7bc5b7c4d..54929203b1f 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -714,6 +714,7 @@ mapAliases ({ pinentry_qt = throw "'pinentry_qt' has been renamed to/replaced by 'pinentry-qt'"; # Converted to throw 2023-09-10 pinentry_qt5 = pinentry-qt; # Added 2020-02-11 poetry2nix = throw "poetry2nix is now maintained out-of-tree. Please use https://github.com/nix-community/poetry2nix/"; # Added 2023-10-26 + prayer = throw "prayer has been removed from nixpkgs"; # Added 2023-11-09 privacyidea = throw "privacyidea has been removed from nixpkgs"; # Added 2023-10-31 probe-rs-cli = throw "probe-rs-cli is now part of the probe-rs package"; # Added 2023-07-03 processing3 = throw "'processing3' has been renamed to/replaced by 'processing'"; # Converted to throw 2023-09-10 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0ba506bab37..9c5e14fa9dd 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -28589,8 +28589,6 @@ with pkgs; pps-tools = callPackage ../os-specific/linux/pps-tools { }; - prayer = callPackage ../servers/prayer { }; - procps = if stdenv.isLinux then callPackage ../os-specific/linux/procps-ng { } else unixtools.procps; -- cgit 1.4.1 From 022ee4d701878c185785ce72dd436639dd687199 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Mon, 30 Oct 2023 14:50:40 +0100 Subject: kibana7: drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depends on EOL software and no maintenance has been attempted to change this after a ping (https://github.com/NixOS/nixpkgs/issues/259178) Feel free to adopt and re-introduce if you care about this software. This will probably seriously hamper ELK usability in nixpkgs, but as it receives no maintenance… --- nixos/modules/module-list.nix | 1 - nixos/modules/services/search/kibana.nix | 213 --------------------- nixos/tests/elk.nix | 14 -- pkgs/development/tools/misc/kibana/7.x.nix | 60 ------ .../kibana/disable-nodejs-version-check-7.patch | 19 -- pkgs/top-level/aliases.nix | 2 + pkgs/top-level/all-packages.nix | 3 - 7 files changed, 2 insertions(+), 310 deletions(-) delete mode 100644 nixos/modules/services/search/kibana.nix delete mode 100644 pkgs/development/tools/misc/kibana/7.x.nix delete mode 100644 pkgs/development/tools/misc/kibana/disable-nodejs-version-check-7.patch (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 00da6399295..2e5b1ce90af 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1147,7 +1147,6 @@ ./services/search/elasticsearch-curator.nix ./services/search/elasticsearch.nix ./services/search/hound.nix - ./services/search/kibana.nix ./services/search/meilisearch.nix ./services/search/opensearch.nix ./services/search/qdrant.nix diff --git a/nixos/modules/services/search/kibana.nix b/nixos/modules/services/search/kibana.nix deleted file mode 100644 index a5e132d5c38..00000000000 --- a/nixos/modules/services/search/kibana.nix +++ /dev/null @@ -1,213 +0,0 @@ -{ config, lib, options, pkgs, ... }: - -with lib; - -let - cfg = config.services.kibana; - opt = options.services.kibana; - - ge7 = builtins.compareVersions cfg.package.version "7" >= 0; - lt6_6 = builtins.compareVersions cfg.package.version "6.6" < 0; - - cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON ( - (filterAttrsRecursive (n: v: v != null && v != []) ({ - server.host = cfg.listenAddress; - server.port = cfg.port; - server.ssl.certificate = cfg.cert; - server.ssl.key = cfg.key; - - kibana.index = cfg.index; - kibana.defaultAppId = cfg.defaultAppId; - - elasticsearch.url = cfg.elasticsearch.url; - elasticsearch.hosts = cfg.elasticsearch.hosts; - elasticsearch.username = cfg.elasticsearch.username; - elasticsearch.password = cfg.elasticsearch.password; - - elasticsearch.ssl.certificate = cfg.elasticsearch.cert; - elasticsearch.ssl.key = cfg.elasticsearch.key; - elasticsearch.ssl.certificateAuthorities = cfg.elasticsearch.certificateAuthorities; - } // cfg.extraConf) - ))); - -in { - options.services.kibana = { - enable = mkEnableOption (lib.mdDoc "kibana service"); - - listenAddress = mkOption { - description = lib.mdDoc "Kibana listening host"; - default = "127.0.0.1"; - type = types.str; - }; - - port = mkOption { - description = lib.mdDoc "Kibana listening port"; - default = 5601; - type = types.port; - }; - - cert = mkOption { - description = lib.mdDoc "Kibana ssl certificate."; - default = null; - type = types.nullOr types.path; - }; - - key = mkOption { - description = lib.mdDoc "Kibana ssl key."; - default = null; - type = types.nullOr types.path; - }; - - index = mkOption { - description = lib.mdDoc "Elasticsearch index to use for saving kibana config."; - default = ".kibana"; - type = types.str; - }; - - defaultAppId = mkOption { - description = lib.mdDoc "Elasticsearch default application id."; - default = "discover"; - type = types.str; - }; - - elasticsearch = { - url = mkOption { - description = lib.mdDoc '' - Elasticsearch url. - - Defaults to `"http://localhost:9200"`. - - Don't set this when using Kibana >= 7.0.0 because it will result in a - configuration error. Use {option}`services.kibana.elasticsearch.hosts` - instead. - ''; - default = null; - type = types.nullOr types.str; - }; - - hosts = mkOption { - description = lib.mdDoc '' - The URLs of the Elasticsearch instances to use for all your queries. - All nodes listed here must be on the same cluster. - - Defaults to `[ "http://localhost:9200" ]`. - - This option is only valid when using kibana >= 6.6. - ''; - default = null; - type = types.nullOr (types.listOf types.str); - }; - - username = mkOption { - description = lib.mdDoc "Username for elasticsearch basic auth."; - default = null; - type = types.nullOr types.str; - }; - - password = mkOption { - description = lib.mdDoc "Password for elasticsearch basic auth."; - default = null; - type = types.nullOr types.str; - }; - - ca = mkOption { - description = lib.mdDoc '' - CA file to auth against elasticsearch. - - It's recommended to use the {option}`certificateAuthorities` option - when using kibana-5.4 or newer. - ''; - default = null; - type = types.nullOr types.path; - }; - - certificateAuthorities = mkOption { - description = lib.mdDoc '' - CA files to auth against elasticsearch. - - Please use the {option}`ca` option when using kibana \< 5.4 - because those old versions don't support setting multiple CA's. - - This defaults to the singleton list [ca] when the {option}`ca` option is defined. - ''; - default = lib.optional (cfg.elasticsearch.ca != null) ca; - defaultText = literalExpression '' - lib.optional (config.${opt.elasticsearch.ca} != null) ca - ''; - type = types.listOf types.path; - }; - - cert = mkOption { - description = lib.mdDoc "Certificate file to auth against elasticsearch."; - default = null; - type = types.nullOr types.path; - }; - - key = mkOption { - description = lib.mdDoc "Key file to auth against elasticsearch."; - default = null; - type = types.nullOr types.path; - }; - }; - - package = mkOption { - description = lib.mdDoc "Kibana package to use"; - default = pkgs.kibana; - defaultText = literalExpression "pkgs.kibana"; - type = types.package; - }; - - dataDir = mkOption { - description = lib.mdDoc "Kibana data directory"; - default = "/var/lib/kibana"; - type = types.path; - }; - - extraConf = mkOption { - description = lib.mdDoc "Kibana extra configuration"; - default = {}; - type = types.attrs; - }; - }; - - config = mkIf (cfg.enable) { - assertions = [ - { - assertion = ge7 -> cfg.elasticsearch.url == null; - message = - "The option services.kibana.elasticsearch.url has been removed when using kibana >= 7.0.0. " + - "Please use option services.kibana.elasticsearch.hosts instead."; - } - { - assertion = lt6_6 -> cfg.elasticsearch.hosts == null; - message = - "The option services.kibana.elasticsearch.hosts is only valid for kibana >= 6.6."; - } - ]; - systemd.services.kibana = { - description = "Kibana Service"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" "elasticsearch.service" ]; - environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; }; - serviceConfig = { - ExecStart = - "${cfg.package}/bin/kibana" + - " --config ${cfgFile}" + - " --path.data ${cfg.dataDir}"; - User = "kibana"; - WorkingDirectory = cfg.dataDir; - }; - }; - - environment.systemPackages = [ cfg.package ]; - - users.users.kibana = { - isSystemUser = true; - description = "Kibana service user"; - home = cfg.dataDir; - createHome = true; - group = "kibana"; - }; - users.groups.kibana = {}; - }; -} diff --git a/nixos/tests/elk.nix b/nixos/tests/elk.nix index 0122bc44036..900ea632010 100644 --- a/nixos/tests/elk.nix +++ b/nixos/tests/elk.nix @@ -119,11 +119,6 @@ let package = elk.elasticsearch; }; - kibana = { - enable = true; - package = elk.kibana; - }; - elasticsearch-curator = { enable = true; actionYAML = '' @@ -217,13 +212,6 @@ let one.wait_until_succeeds("cat /tmp/logstash.out | grep flowers") one.wait_until_succeeds("cat /tmp/logstash.out | grep -v dragons") - with subtest("Kibana is healthy"): - one.wait_for_unit("kibana.service") - one.wait_until_succeeds( - "curl --silent --show-error --fail-with-body 'http://localhost:5601/api/status'" - + " | jq -es 'if . == [] then null else .[] | .status.overall.state == \"green\" end'" - ) - with subtest("Metricbeat is running"): one.wait_for_unit("metricbeat.service") @@ -274,7 +262,6 @@ in { # name = "elk-7"; # elasticsearch = pkgs.elasticsearch7-oss; # logstash = pkgs.logstash7-oss; - # kibana = pkgs.kibana7-oss; # filebeat = pkgs.filebeat7; # metricbeat = pkgs.metricbeat7; # }; @@ -282,7 +269,6 @@ in { ELK-7 = mkElkTest "elk-7" { elasticsearch = pkgs.elasticsearch7; logstash = pkgs.logstash7; - kibana = pkgs.kibana7; filebeat = pkgs.filebeat7; metricbeat = pkgs.metricbeat7; }; diff --git a/pkgs/development/tools/misc/kibana/7.x.nix b/pkgs/development/tools/misc/kibana/7.x.nix deleted file mode 100644 index a4faa31a421..00000000000 --- a/pkgs/development/tools/misc/kibana/7.x.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ elk7Version -, enableUnfree ? true -, lib -, stdenv -, makeWrapper -, fetchurl -, nodejs_16 -, coreutils -, which -}: - -let - nodejs = nodejs_16; - inherit (builtins) elemAt; - info = lib.splitString "-" stdenv.hostPlatform.system; - arch = elemAt info 0; - plat = elemAt info 1; - hashes = - { - x86_64-linux = "sha512-09XokG5krjxGnk34DhxpLOGRLjb2jd82uZtwGfrzSuuqMpBhkEptK2oySGxuGdHF8uowwlR5p5YO2TvBwMsWkQ=="; - x86_64-darwin = "sha512-cqRJnvu730Jfkr6vwbHUFuZube1g522cmvnDwTzhGGK6VN/7+9XL3vavqtUPDVdTLTUk+DrNiIQK7MaJH3SHMg=="; - aarch64-linux = "sha512-zhtYThz5j4+w5gI1JWSnHv709Tk23eegVsrtYmdaYhZiTw2yvCTYI5uNAfBjBr8XPdp6CKF4e6Bh2wHKDYg1mg=="; - aarch64-darwin = "sha512-cqRJnvu730Jfkr6vwbHUFuZube1g522cmvnDwTzhGGK6VN/7+9XL3vavqtUPDVdTLTUk+DrNiIQK7MaJH3SHMg=="; - }; - -in stdenv.mkDerivation rec { - pname = "kibana"; - version = elk7Version; - - src = fetchurl { - url = "https://artifacts.elastic.co/downloads/kibana/${pname}-${version}-${plat}-${arch}.tar.gz"; - hash = hashes.${stdenv.hostPlatform.system} or (throw "Unknown architecture"); - }; - - patches = [ - # Kibana specifies it specifically needs nodejs 10.15.2 but nodejs in nixpkgs is at 10.15.3. - # The test succeeds with this newer version so lets just - # disable the version check. - ./disable-nodejs-version-check-7.patch - ]; - - nativeBuildInputs = [ makeWrapper ]; - - installPhase = '' - mkdir -p $out/libexec/kibana $out/bin - mv * $out/libexec/kibana/ - rm -r $out/libexec/kibana/node - makeWrapper $out/libexec/kibana/bin/kibana $out/bin/kibana \ - --prefix PATH : "${lib.makeBinPath [ nodejs coreutils which ]}" - sed -i 's@NODE=.*@NODE=${nodejs}/bin/node@' $out/libexec/kibana/bin/kibana - ''; - - meta = with lib; { - description = "Visualize logs and time-stamped data"; - homepage = "http://www.elasticsearch.org/overview/kibana"; - license = licenses.elastic20; - maintainers = with maintainers; [ offline basvandijk ]; - platforms = with platforms; unix; - }; -} diff --git a/pkgs/development/tools/misc/kibana/disable-nodejs-version-check-7.patch b/pkgs/development/tools/misc/kibana/disable-nodejs-version-check-7.patch deleted file mode 100644 index ef4c207764c..00000000000 --- a/pkgs/development/tools/misc/kibana/disable-nodejs-version-check-7.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/src/setup_node_env/node_version_validator.js b/src/setup_node_env/node_version_validator.js -index 3f611e5a..f5c60c85 100644 ---- a/src/setup_node_env/node_version_validator.js -+++ b/src/setup_node_env/node_version_validator.js -@@ -25,11 +25,11 @@ var pkg = require('../../package.json'); // Note: This is written in ES5 so we c - var currentVersion = process && process.version || null; - var rawRequiredVersion = pkg && pkg.engines && pkg.engines.node || null; - var requiredVersion = rawRequiredVersion ? 'v' + rawRequiredVersion : rawRequiredVersion; --var isVersionValid = !!currentVersion && !!requiredVersion && currentVersion === requiredVersion; // Validates current the NodeJS version compatibility when Kibana starts. -+var isVersionValid = !!currentVersion && !!requiredVersion; // Validates current the NodeJS version compatibility when Kibana starts. - - if (!isVersionValid) { - var errorMessage = 'Kibana does not support the current Node.js version ' + currentVersion + '. Please use Node.js ' + requiredVersion + '.'; // Actions to apply when validation fails: error report + exit. - - console.error(errorMessage); - process.exit(1); --} -\ No newline at end of file -+} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index f3db0c7c791..ef11a126762 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -428,6 +428,8 @@ mapAliases ({ keysmith = libsForQt5.kdeGear.keysmith; # Added 2021-07-14 kfctl = throw "kfctl is broken and has been archived by upstream" ; # Added 2023-08-21 kgx = gnome-console; # Added 2022-02-19 + kibana7 = throw "Kibana 7.x has been removed from nixpkgs as it depends on an end of life Node.js version and received no maintenance in time."; # Added 2023-30-10 + kibana = kibana7; kicad-with-packages3d = throw "'kicad-with-packages3d' has been renamed to/replaced by 'kicad'"; # Converted to throw 2023-09-10 kio-admin = libsForQt5.kdeGear.kio-admin; # Added 2023-03-18 kodiGBM = kodi-gbm; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a7716efbab3..963f4bfdaa7 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -9830,9 +9830,6 @@ with pkgs; kluctl = callPackage ../applications/networking/cluster/kluctl { }; - kibana7 = callPackage ../development/tools/misc/kibana/7.x.nix { }; - kibana = kibana7; - kibi = callPackage ../applications/editors/kibi { }; kio-fuse = libsForQt5.callPackage ../tools/filesystems/kio-fuse { }; -- cgit 1.4.1 From 72911a99d34a4d290671728d40016ba5254f72fe Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Wed, 8 Nov 2023 16:38:01 +0100 Subject: code-server: drop Depends on Node.js 16 and cannot be trivially upgraded to Node.js 18. --- nixos/modules/module-list.nix | 1 - nixos/modules/services/web-apps/code-server.nix | 259 ---------------- nixos/tests/all-tests.nix | 1 - nixos/tests/code-server.nix | 22 -- pkgs/servers/code-server/build-vscode-nogit.patch | 20 -- pkgs/servers/code-server/default.nix | 327 --------------------- pkgs/servers/code-server/playwright.patch | 10 - .../servers/code-server/remove-node-download.patch | 28 -- pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 7 - 10 files changed, 1 insertion(+), 675 deletions(-) delete mode 100644 nixos/modules/services/web-apps/code-server.nix delete mode 100644 nixos/tests/code-server.nix delete mode 100644 pkgs/servers/code-server/build-vscode-nogit.patch delete mode 100644 pkgs/servers/code-server/default.nix delete mode 100644 pkgs/servers/code-server/playwright.patch delete mode 100644 pkgs/servers/code-server/remove-node-download.patch (limited to 'nixos/modules/module-list.nix') diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2e5b1ce90af..d02c5b593b3 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1240,7 +1240,6 @@ ./services/web-apps/changedetection-io.nix ./services/web-apps/chatgpt-retrieval-plugin.nix ./services/web-apps/cloudlog.nix - ./services/web-apps/code-server.nix ./services/web-apps/convos.nix ./services/web-apps/dex.nix ./services/web-apps/discourse.nix diff --git a/nixos/modules/services/web-apps/code-server.nix b/nixos/modules/services/web-apps/code-server.nix deleted file mode 100644 index 11601f6c304..00000000000 --- a/nixos/modules/services/web-apps/code-server.nix +++ /dev/null @@ -1,259 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - cfg = config.services.code-server; - defaultUser = "code-server"; - defaultGroup = defaultUser; -in { - options = { - services.code-server = { - enable = lib.mkEnableOption (lib.mdDoc "code-server"); - - package = lib.mkPackageOptionMD pkgs "code-server" { - example = '' - pkgs.vscode-with-extensions.override { - vscode = pkgs.code-server; - vscodeExtensions = with pkgs.vscode-extensions; [ - bbenoist.nix - dracula-theme.theme-dracula - ]; - } - ''; - }; - - extraPackages = lib.mkOption { - default = [ ]; - description = lib.mdDoc '' - Additional packages to add to the code-server {env}`PATH`. - ''; - example = lib.literalExpression "[ pkgs.go ]"; - type = lib.types.listOf lib.types.package; - }; - - extraEnvironment = lib.mkOption { - type = lib.types.attrsOf lib.types.str; - description = lib.mdDoc '' - Additional environment variables to pass to code-server. - ''; - default = { }; - example = { PKG_CONFIG_PATH = "/run/current-system/sw/lib/pkgconfig"; }; - }; - - extraArguments = lib.mkOption { - default = [ ]; - description = lib.mdDoc '' - Additional arguments to pass to code-server. - ''; - example = lib.literalExpression ''[ "--log=info" ]''; - type = lib.types.listOf lib.types.str; - }; - - host = lib.mkOption { - default = "localhost"; - description = lib.mdDoc '' - The host name or IP address the server should listen to. - ''; - type = lib.types.str; - }; - - port = lib.mkOption { - default = 4444; - description = lib.mdDoc '' - The port the server should listen to. - ''; - type = lib.types.port; - }; - - auth = lib.mkOption { - default = "password"; - description = lib.mdDoc '' - The type of authentication to use. - ''; - type = lib.types.enum [ "none" "password" ]; - }; - - hashedPassword = lib.mkOption { - default = ""; - description = lib.mdDoc '' - Create the password with: `echo -n 'thisismypassword' | npx argon2-cli -e`. - ''; - type = lib.types.str; - }; - - user = lib.mkOption { - default = defaultUser; - example = "yourUser"; - description = lib.mdDoc '' - The user to run code-server as. - By default, a user named `${defaultUser}` will be created. - ''; - type = lib.types.str; - }; - - group = lib.mkOption { - default = defaultGroup; - example = "yourGroup"; - description = lib.mdDoc '' - The group to run code-server under. - By default, a group named `${defaultGroup}` will be created. - ''; - type = lib.types.str; - }; - - extraGroups = lib.mkOption { - default = [ ]; - description = lib.mdDoc '' - An array of additional groups for the `${defaultUser}` user. - ''; - example = [ "docker" ]; - type = lib.types.listOf lib.types.str; - }; - - socket = lib.mkOption { - default = null; - example = "/run/code-server/socket"; - description = lib.mdDoc '' - Path to a socket (bind-addr will be ignored). - ''; - type = lib.types.nullOr lib.types.str; - }; - - socketMode = lib.mkOption { - default = null; - description = lib.mdDoc '' - File mode of the socket. - ''; - type = lib.types.nullOr lib.types.str; - }; - - userDataDir = lib.mkOption { - default = null; - description = lib.mdDoc '' - Path to the user data directory. - ''; - type = lib.types.nullOr lib.types.str; - }; - - extensionsDir = lib.mkOption { - default = null; - description = lib.mdDoc '' - Path to the extensions directory. - ''; - type = lib.types.nullOr lib.types.str; - }; - - proxyDomain = lib.mkOption { - default = null; - example = "code-server.lan"; - description = lib.mdDoc '' - Domain used for proxying ports. - ''; - type = lib.types.nullOr lib.types.str; - }; - - disableTelemetry = lib.mkOption { - default = false; - example = true; - description = lib.mdDoc '' - Disable telemetry. - ''; - type = lib.types.bool; - }; - - disableUpdateCheck = lib.mkOption { - default = false; - example = true; - description = lib.mdDoc '' - Disable update check. - Without this flag, code-server checks every 6 hours against the latest github release and - then notifies you once every week that a new release is available. - ''; - type = lib.types.bool; - }; - - disableFileDownloads = lib.mkOption { - default = false; - example = true; - description = lib.mdDoc '' - Disable file downloads from Code. - ''; - type = lib.types.bool; - }; - - disableWorkspaceTrust = lib.mkOption { - default = false; - example = true; - description = lib.mdDoc '' - Disable Workspace Trust feature. - ''; - type = lib.types.bool; - }; - - disableGettingStartedOverride = lib.mkOption { - default = false; - example = true; - description = lib.mdDoc '' - Disable the coder/coder override in the Help: Getting Started page. - ''; - type = lib.types.bool; - }; - - }; - }; - - config = lib.mkIf cfg.enable { - systemd.services.code-server = { - description = "Code server"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-online.target" ]; - path = cfg.extraPackages; - environment = { - HASHED_PASSWORD = cfg.hashedPassword; - } // cfg.extraEnvironment; - serviceConfig = { - ExecStart = '' - ${lib.getExe cfg.package} \ - --auth=${cfg.auth} \ - --bind-addr=${cfg.host}:${toString cfg.port} \ - '' + lib.optionalString (cfg.socket != null) '' - --socket=${cfg.socket} \ - '' + lib.optionalString (cfg.userDataDir != null) '' - --user-data-dir=${cfg.userDataDir} \ - '' + lib.optionalString (cfg.extensionsDir != null) '' - --extensions-dir=${cfg.extensionsDir} \ - '' + lib.optionalString (cfg.disableTelemetry == true) '' - --disable-telemetry \ - '' + lib.optionalString (cfg.disableUpdateCheck == true) '' - --disable-update-check \ - '' + lib.optionalString (cfg.disableFileDownloads == true) '' - --disable-file-downloads \ - '' + lib.optionalString (cfg.disableWorkspaceTrust == true) '' - --disable-workspace-trust \ - '' + lib.optionalString (cfg.disableGettingStartedOverride == true) '' - --disable-getting-started-override \ - '' + lib.escapeShellArgs cfg.extraArguments; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - RuntimeDirectory = cfg.user; - User = cfg.user; - Group = cfg.group; - Restart = "on-failure"; - }; - }; - - users.users."${cfg.user}" = lib.mkMerge [ - (lib.mkIf (cfg.user == defaultUser) { - isNormalUser = true; - description = "code-server user"; - inherit (cfg) group; - }) - { - packages = cfg.extraPackages; - inherit (cfg) extraGroups; - } - ]; - - users.groups."${defaultGroup}" = lib.mkIf (cfg.group == defaultGroup) { }; - }; - - meta.maintainers = [ lib.maintainers.stackshadow ]; -} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 6c127efa4ce..6a654b00d76 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -192,7 +192,6 @@ in { cntr = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cntr.nix {}; cockpit = handleTest ./cockpit.nix {}; cockroachdb = handleTestOn ["x86_64-linux"] ./cockroachdb.nix {}; - code-server = handleTest ./code-server.nix {}; coder = handleTest ./coder.nix {}; collectd = handleTest ./collectd.nix {}; connman = handleTest ./connman.nix {}; diff --git a/nixos/tests/code-server.nix b/nixos/tests/code-server.nix deleted file mode 100644 index 7d523dfc617..00000000000 --- a/nixos/tests/code-server.nix +++ /dev/null @@ -1,22 +0,0 @@ -import ./make-test-python.nix ({pkgs, lib, ...}: -{ - name = "code-server"; - - nodes = { - machine = {pkgs, ...}: { - services.code-server = { - enable = true; - auth = "none"; - }; - }; - }; - - testScript = '' - start_all() - machine.wait_for_unit("code-server.service") - machine.wait_for_open_port(4444) - machine.succeed("curl -k --fail http://localhost:4444", timeout=10) - ''; - - meta.maintainers = [ lib.maintainers.drupol ]; -}) diff --git a/pkgs/servers/code-server/build-vscode-nogit.patch b/pkgs/servers/code-server/build-vscode-nogit.patch deleted file mode 100644 index ec726c68d43..00000000000 --- a/pkgs/servers/code-server/build-vscode-nogit.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/ci/build/build-vscode.sh b/ci/build/build-vscode.sh -index a72549fb..3aed1ad5 100755 ---- a/ci/build/build-vscode.sh -+++ b/ci/build/build-vscode.sh -@@ -58,7 +58,6 @@ main() { - # telemetry available; telemetry can still be disabled by flag or setting). - # This needs to be done before building as Code will read this file and embed - # it into the client-side code. -- git checkout product.json # Reset in case the script exited early. - cp product.json product.original.json # Since jq has no inline edit. - jq --slurp '.[0] * .[1]' product.original.json <( - cat << EOF -@@ -105,7 +104,6 @@ EOF - # Reset so if you develop after building you will not be stuck with the wrong - # commit (the dev client will use `oss-dev` but the dev server will still use - # product.json which will have `stable-$commit`). -- git checkout product.json - - popd - diff --git a/pkgs/servers/code-server/default.nix b/pkgs/servers/code-server/default.nix deleted file mode 100644 index 0c5cb231085..00000000000 --- a/pkgs/servers/code-server/default.nix +++ /dev/null @@ -1,327 +0,0 @@ -{ lib -, stdenv -, fetchFromGitHub -, buildGoModule -, makeWrapper -, cacert -, moreutils -, jq -, git -, rsync -, pkg-config -, yarn -, python3 -, esbuild -, nodejs -, node-gyp -, libsecret -, xorg -, ripgrep -, AppKit -, Cocoa -, CoreServices -, Security -, cctools -, xcbuild -, quilt -, nixosTests -}: - -let - system = stdenv.hostPlatform.system; - - python = python3; - yarn' = yarn.override { inherit nodejs; }; - defaultYarnOpts = [ ]; - - esbuild' = esbuild.override { - buildGoModule = args: buildGoModule (args // rec { - version = "0.16.17"; - src = fetchFromGitHub { - owner = "evanw"; - repo = "esbuild"; - rev = "v${version}"; - hash = "sha256-8L8h0FaexNsb3Mj6/ohA37nYLFogo5wXkAhGztGUUsQ="; - }; - vendorHash = "sha256-+BfxCyg0KkDQpHt/wycy/8CTG6YBA/VJvJFhhzUnSiQ="; - }); - }; - - # replaces esbuild's download script with a binary from nixpkgs - patchEsbuild = path: version: '' - mkdir -p ${path}/node_modules/esbuild/bin - jq "del(.scripts.postinstall)" ${path}/node_modules/esbuild/package.json | sponge ${path}/node_modules/esbuild/package.json - sed -i 's/${version}/${esbuild'.version}/g' ${path}/node_modules/esbuild/lib/main.js - ln -s -f ${esbuild'}/bin/esbuild ${path}/node_modules/esbuild/bin/esbuild - ''; - - # Comment from @code-asher, the code-server maintainer - # See https://github.com/NixOS/nixpkgs/pull/240001#discussion_r1244303617 - # - # If the commit is missing it will break display languages (Japanese, Spanish, - # etc). For some reason VS Code has a hard dependency on the commit being set - # for that functionality. - # The commit is also used in cache busting. Without the commit you could run - # into issues where the browser is loading old versions of assets from the - # cache. - # Lastly, it can be helpful for the commit to be accurate in bug reports - # especially when they are built outside of our CI as sometimes the version - # numbers can be unreliable (since they are arbitrarily provided). - # - # To compute the commit when upgrading this derivation, do: - # `$ git rev-parse ` where is the git revision of the `src` - # Example: `$ git rev-parse v4.16.1` - commit = "94ef3776ad7bebfb5780dfc9632e04d20d5c9a6c"; -in -stdenv.mkDerivation (finalAttrs: { - pname = "code-server"; - version = "4.16.1"; - - src = fetchFromGitHub { - owner = "coder"; - repo = "code-server"; - rev = "v${finalAttrs.version}"; - fetchSubmodules = true; - hash = "sha256-h4AooHHKV/EfN2S1z7CQKqnYW3uA3sKhSW4senlzjxI="; - }; - - yarnCache = stdenv.mkDerivation { - name = "${finalAttrs.pname}-${finalAttrs.version}-${system}-yarn-cache"; - inherit (finalAttrs) src; - - nativeBuildInputs = [ yarn' git cacert ]; - - buildPhase = '' - runHook preBuild - - export HOME=$PWD - export GIT_SSL_CAINFO="${cacert}/etc/ssl/certs/ca-bundle.crt" - - yarn --cwd "./vendor" install --modules-folder modules --ignore-scripts --frozen-lockfile - - yarn config set yarn-offline-mirror $out - find "$PWD" -name "yarn.lock" -printf "%h\n" | \ - xargs -I {} yarn --cwd {} \ - --frozen-lockfile --ignore-scripts --ignore-platform \ - --ignore-engines --no-progress --non-interactive - - find ./lib/vscode -name "yarn.lock" -printf "%h\n" | \ - xargs -I {} yarn --cwd {} \ - --ignore-scripts --ignore-engines - - runHook postBuild - ''; - - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - outputHash = "sha256-vkju+oxEYrEXFAnjz/Mf1g0ZhxBALLAaRuWE0swSWwM="; - }; - - nativeBuildInputs = [ - nodejs - yarn' - python - pkg-config - makeWrapper - git - rsync - jq - moreutils - quilt - ]; - - buildInputs = lib.optionals (!stdenv.isDarwin) [ libsecret ] - ++ (with xorg; [ libX11 libxkbfile ]) - ++ lib.optionals stdenv.isDarwin [ - AppKit - Cocoa - CoreServices - Security - cctools - xcbuild - ]; - - patches = [ - # Remove all git calls from the VS Code build script except `git rev-parse - # HEAD` which is replaced in postPatch with the commit. - ./build-vscode-nogit.patch - ]; - - postPatch = '' - export HOME=$PWD - - patchShebangs ./ci - - # inject git commit - substituteInPlace ./ci/build/build-vscode.sh \ - --replace '$(git rev-parse HEAD)' "${commit}" - substituteInPlace ./ci/build/build-release.sh \ - --replace '$(git rev-parse HEAD)' "${commit}" - ''; - - configurePhase = '' - runHook preConfigure - - # run yarn offline by default - echo '--install.offline true' >> .yarnrc - - # set default yarn opts - ${lib.concatMapStrings (option: '' - yarn --offline config set ${option} - '') defaultYarnOpts} - - # set offline mirror to yarn cache we created in previous steps - yarn --offline config set yarn-offline-mirror "${finalAttrs.yarnCache}" - - # skip unnecessary electron download - export ELECTRON_SKIP_BINARY_DOWNLOAD=1 - - # set nodedir to prevent node-gyp from downloading headers - # taken from https://nixos.org/manual/nixpkgs/stable/#javascript-tool-specific - mkdir -p $HOME/.node-gyp/${nodejs.version} - echo 9 > $HOME/.node-gyp/${nodejs.version}/installVersion - ln -sfv ${nodejs}/include $HOME/.node-gyp/${nodejs.version} - export npm_config_nodedir=${nodejs} - - # use updated node-gyp. fixes the following error on Darwin: - # PermissionError: [Errno 1] Operation not permitted: '/usr/sbin/pkgutil' - export npm_config_node_gyp=${node-gyp}/lib/node_modules/node-gyp/bin/node-gyp.js - - runHook postConfigure - ''; - - buildPhase = '' - runHook preBuild - - # install code-server dependencies - yarn --offline --ignore-scripts - - # apply patches - quilt push -a - - # patch shebangs of everything to allow binary packages to build - patchShebangs . - - export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 - export SKIP_SUBMODULE_DEPS=1 - export NODE_OPTIONS=--openssl-legacy-provider - - # rebuild binary packages now that scripts have been patched - echo "----- NPM rebuild" - npm rebuild --prefer-offline - - # Replicate ci/dev/postinstall.sh - echo "----- Replicate ci/dev/postinstall.sh" - yarn --cwd "./vendor" install --modules-folder modules --offline --ignore-scripts --frozen-lockfile - - # remove all built-in extensions, as these are 3rd party extensions that - # get downloaded from vscode marketplace - jq --slurp '.[0] * .[1]' "./lib/vscode/product.json" <( - cat << EOF - { - "builtInExtensions": [] - } - EOF - ) | sponge ./lib/vscode/product.json - - # disable automatic updates - sed -i '/update.mode/,/\}/{s/default:.*/default: "none",/g}' \ - lib/vscode/src/vs/platform/update/common/update.config.contribution.ts - - # Patch out remote download of nodejs from build script - patch -p1 -i ${./remove-node-download.patch} - - # Fetch packages for vscode - find ./lib/vscode -name "yarn.lock" -printf "%h\n" | \ - xargs -I {} yarn --cwd {} \ - --frozen-lockfile --ignore-scripts --ignore-engines - - # patch shebangs of everything to allow binary packages to build - patchShebangs . - - ${patchEsbuild "./lib/vscode/build" "0.12.6"} - ${patchEsbuild "./lib/vscode/extensions" "0.11.23"} - '' + lib.optionalString stdenv.isDarwin '' - # use prebuilt binary for @parcel/watcher, which requires macOS SDK 10.13+ - # (see issue #101229) - pushd ./lib/vscode/remote/node_modules/@parcel/watcher - mkdir -p ./build/Release - mv ./prebuilds/darwin-x64/node.napi.glibc.node ./build/Release/watcher.node - jq "del(.scripts) | .gypfile = false" ./package.json | sponge ./package.json - popd - '' + '' - - # put ripgrep binary into bin, so postinstall does not try to download it - find -name ripgrep -type d \ - -execdir mkdir -p {}/bin \; \ - -execdir ln -s ${ripgrep}/bin/rg {}/bin/rg \; - - # run postinstall scripts after patching - find ./lib/vscode \( -path "*/node_modules/*" -or -path "*/extensions/*" \) \ - -and -type f -name "yarn.lock" -printf "%h\n" | \ - xargs -I {} sh -c 'jq -e ".scripts.postinstall" {}/package.json >/dev/null && yarn --cwd {} postinstall --frozen-lockfile --offline || true' - - # build code-server - yarn build - - # build vscode - VERSION=${finalAttrs.version} yarn build:vscode - - # inject version into package.json - jq --slurp '.[0] * .[1]' ./package.json <( - cat << EOF - { - "version": "${finalAttrs.version}" - } - EOF - ) | sponge ./package.json - - # create release - yarn release - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out/libexec/code-server $out/bin - - # copy release to libexec path - cp -R -T release "$out/libexec/code-server" - - # install only production dependencies - yarn --offline --cwd "$out/libexec/code-server" --production - - # create wrapper - makeWrapper "${nodejs}/bin/node" "$out/bin/code-server" \ - --add-flags "$out/libexec/code-server/out/node/entry.js" - - runHook postInstall - ''; - - passthru = { - prefetchYarnCache = lib.overrideDerivation finalAttrs.yarnCache (d: { - outputHash = lib.fakeSha256; - }); - tests = { - inherit (nixosTests) code-server; - }; - # vscode-with-extensions compatibility - executableName = "code-server"; - longName = "Visual Studio Code Server"; - }; - - meta = { - description = "Run VS Code on a remote server"; - longDescription = '' - code-server is VS Code running on a remote server, accessible through the - browser. - ''; - homepage = "https://github.com/coder/code-server"; - license = lib.licenses.mit; - maintainers = with lib.maintainers; [ offline henkery code-asher ]; - platforms = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ]; - mainProgram = "code-server"; - }; -}) diff --git a/pkgs/servers/code-server/playwright.patch b/pkgs/servers/code-server/playwright.patch deleted file mode 100644 index 95a74748189..00000000000 --- a/pkgs/servers/code-server/playwright.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- ./vendor/modules/code-oss-dev/node_modules/playwright/install.js -+++ ./vendor/modules/code-oss-dev/node_modules/playwright/install.js -@@ -14,6 +14,4 @@ - * limitations under the License. - */ - --const { installDefaultBrowsersForNpmInstall } = require('playwright-core/lib/utils/registry'); -- --installDefaultBrowsersForNpmInstall(); -+process.stdout.write('Browser install disabled by Nix build script\n'); diff --git a/pkgs/servers/code-server/remove-node-download.patch b/pkgs/servers/code-server/remove-node-download.patch deleted file mode 100644 index d19d4a2b5bf..00000000000 --- a/pkgs/servers/code-server/remove-node-download.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- ./lib/vscode/build/gulpfile.reh.js -+++ ./lib/vscode/build/gulpfile.reh.js -@@ -268,9 +268,6 @@ - .pipe(util.stripSourceMappingURL()) - .pipe(jsFilter.restore); - -- const nodePath = `.build/node/v${nodeVersion}/${platform}-${arch}`; -- const node = gulp.src(`${nodePath}/**`, { base: nodePath, dot: true }); -- - let web = []; - if (type === 'reh-web') { - web = [ -@@ -287,7 +284,6 @@ - license, - sources, - deps, -- node, - ...web - ); - -@@ -385,7 +381,6 @@ - const destinationFolderName = `vscode-${type}${dashed(platform)}${dashed(arch)}`; - - const serverTaskCI = task.define(`vscode-${type}${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series( -- gulp.task(`node-${platform}-${arch}`), - util.rimraf(path.join(BUILD_ROOT, destinationFolderName)), - packageTask(type, platform, arch, sourceFolderName, destinationFolderName) - )); diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index ef11a126762..22d68425f92 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -152,6 +152,7 @@ mapAliases ({ clasp = clingo; # added 2022-12-22 claws-mail-gtk3 = claws-mail; # Added 2021-07-10 cntk = throw "'cntk' has been removed from nixpkgs, as it was broken and unmaintained"; # Added 2023-10-09 + code-server = throw "'code-server' has been removed from nixpkgs, as it was depending on EOL Node.js and is unmaintained."; # Added 2023-10-30 codimd = hedgedoc; # Added 2020-11-29 inherit (libsForQt5.mauiPackages) communicator; # added 2022-05-17 compton = throw "'compton' has been renamed to/replaced by 'picom'"; # Converted to throw 2023-09-10 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 963f4bfdaa7..e9db1654159 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -36345,13 +36345,6 @@ with pkgs; inherit (nodePackages) node-gyp; }; - code-server = callPackage ../servers/code-server { - nodejs = nodejs_16; - inherit (darwin.apple_sdk.frameworks) AppKit Cocoa CoreServices Security; - inherit (darwin) cctools; - inherit (nodePackages) node-gyp; - }; - vue = callPackage ../applications/misc/vue { }; vuze = callPackage ../applications/networking/p2p/vuze { -- cgit 1.4.1