From b3a2a87065e240087972f19c1b245a46d5b390d2 Mon Sep 17 00:00:00 2001 From: Chris Dombroski Date: Wed, 21 Aug 2024 22:09:46 -0400 Subject: [PATCH] nixos/zwave-js-ui: init module Provides systemd service and allows configuration of data directory --- .../manual/release-notes/rl-2411.section.md | 2 + nixos/modules/module-list.nix | 1 + .../services/home-automation/zwave-js-ui.nix | 86 +++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/zwave-js-ui.nix | 28 ++++++ 5 files changed, 118 insertions(+) create mode 100644 nixos/modules/services/home-automation/zwave-js-ui.nix create mode 100644 nixos/tests/zwave-js-ui.nix diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index d83c31a9fce805..de1509a55290f5 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -149,6 +149,8 @@ - [ToDesk](https://www.todesk.com/linux.html), a remote desktop applicaton. Available as [services.todesk.enable](#opt-services.todesk.enable). +- [zwave-js-ui](https://zwave-js.github.io/zwave-js-ui/), a full featured Z-Wave Control Panel and MQTT Gateway. Available as [services.zwave-js-ui](#opt-services.zwave-js-ui.enable). + - [Dependency Track](https://dependencytrack.org/), an intelligent Component Analysis platform that allows organizations to identify and reduce risk in the software supply chain. Available as [services.dependency-track](option.html#opt-services.dependency-track). ## Backward Incompatibilities {#sec-release-24.11-incompatibilities} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4a97be04fe7fce..fd7cd8a38e75e6 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -638,6 +638,7 @@ ./services/home-automation/wyoming/satellite.nix ./services/home-automation/zigbee2mqtt.nix ./services/home-automation/zwave-js.nix + ./services/home-automation/zwave-js-ui.nix ./services/logging/SystemdJournal2Gelf.nix ./services/logging/awstats.nix ./services/logging/filebeat.nix diff --git a/nixos/modules/services/home-automation/zwave-js-ui.nix b/nixos/modules/services/home-automation/zwave-js-ui.nix new file mode 100644 index 00000000000000..76b9cfc0544582 --- /dev/null +++ b/nixos/modules/services/home-automation/zwave-js-ui.nix @@ -0,0 +1,86 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (lib) + mkIf + mkEnableOption + mkOption + types + ; + cfg = config.services.zwave-js-ui; +in +{ + options.services.zwave-js-ui = { + enable = mkEnableOption "zwave-js-ui"; + serialPort = mkOption { + type = types.path; + description = '' + Serial port for the Z-Wave controller. + + Used for permissions only; must be additionally set in the application + ''; + example = "/dev/ttyUSB0"; + }; + }; + config = mkIf cfg.enable { + assertions = [ + { + assertion = !config.services.zwave-js.enable; + message = "zwave-js-ui conflicts with zwave-js"; + } + ]; + systemd.services.zwave-js-ui = { + environment = { + STORE_DIR = "/var/lib/zwave-js-ui"; + ZWAVEJS_EXTERNAL_CONFIG = "/var/lib/zwave-js-ui/.config-db"; + }; + script = "${pkgs.zwave-js-ui}/bin/zwave-js-ui"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + RuntimeDirectory = "zwave-js-ui"; + StateDirectory = "zwave-js-ui"; + RootDirectory = "/run/zwave-js-ui"; + BindReadOnlyPaths = [ + "/etc" + "/nix/store" + ]; + BindPaths = [ "/var/lib/zwave-js-ui" ]; + DeviceAllow = [ cfg.serialPort ]; + DynamicUser = true; + SupplementaryGroups = [ "dialout" ]; + CapabilityBoundingSet = ""; + RestrictAddressFamilies = "AF_INET AF_INET6"; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = false; + NoNewPrivileges = true; + PrivateUsers = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernalTunables = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service @pkey" + "~@privileged @resources" + ]; + UMask = "0077"; + }; + }; + }; + meta.maintainers = with lib.maintainers; [ cdombroski ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a625cd92e236d5..c09d84d0226fcd 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1136,4 +1136,5 @@ in { zrepl = handleTest ./zrepl.nix {}; zsh-history = handleTest ./zsh-history.nix {}; zwave-js = handleTest ./zwave-js.nix {}; + zwave-js-ui = handleTest ./zwave-js-ui.nix {}; } diff --git a/nixos/tests/zwave-js-ui.nix b/nixos/tests/zwave-js-ui.nix new file mode 100644 index 00000000000000..75c91364bdfe4f --- /dev/null +++ b/nixos/tests/zwave-js-ui.nix @@ -0,0 +1,28 @@ +import ./make-test-python.nix ( + { lib, ... }: + + { + name = "zwave-js-ui"; + meta.maintainers = with lib.maintainers; [ cdombroski ]; + + nodes = { + machine = + { ... }: + { + services.zwave-js-ui = { + enable = true; + serialPort = "/dev/null"; + }; + }; + }; + + testScript = '' + start_all() + + machine.wait_for_unit("zwave-js-ui.service") + machine.wait_for_open_port(8091) + machine.wait_until_succeeds("journalctl --since -1m --unit zwave-js-ui --grep 'Listening on port 8091 protocol HTTP'") + machine.wait_for_file("/var/lib/zwave-js-ui/nodes.json") + ''; + } +)