home-assistant: refresh cherry-picks (#363666)
This commit is contained in:
@@ -1,8 +1,41 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
any
|
||||
attrByPath
|
||||
attrValues
|
||||
concatMap
|
||||
converge
|
||||
elem
|
||||
escapeShellArg
|
||||
escapeShellArgs
|
||||
filter
|
||||
filterAttrsRecursive
|
||||
hasAttrByPath
|
||||
isAttrs
|
||||
isDerivation
|
||||
isList
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkRemovedOptionModule
|
||||
mkRenamedOptionModule
|
||||
optionals
|
||||
optionalString
|
||||
recursiveUpdate
|
||||
singleton
|
||||
splitString
|
||||
types
|
||||
unique
|
||||
;
|
||||
|
||||
inherit (utils)
|
||||
escapeSystemdExecArgs
|
||||
;
|
||||
|
||||
cfg = config.services.home-assistant;
|
||||
format = pkgs.formats.yaml {};
|
||||
|
||||
@@ -17,7 +50,7 @@ let
|
||||
|
||||
# Filter null values from the configuration, so that we can still advertise
|
||||
# optional options in the config attribute.
|
||||
filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! elem v [ null ])) (lib.recursiveUpdate customLovelaceModulesResources (cfg.config or {}));
|
||||
filteredConfig = converge (filterAttrsRecursive (_: v: ! elem v [ null ])) (recursiveUpdate customLovelaceModulesResources (cfg.config or {}));
|
||||
configFile = renderYAMLFile "configuration.yaml" filteredConfig;
|
||||
|
||||
lovelaceConfigFile = renderYAMLFile "ui-lovelace.yaml" cfg.lovelaceConfig;
|
||||
@@ -42,7 +75,7 @@ let
|
||||
if isDerivation config then
|
||||
[ ]
|
||||
else if isAttrs config then
|
||||
optional (config ? platform) config.platform
|
||||
optionals (config ? platform) [ config.platform ]
|
||||
++ concatMap usedPlatforms (attrValues config)
|
||||
else if isList config then
|
||||
concatMap usedPlatforms config
|
||||
@@ -67,7 +100,7 @@ let
|
||||
extraComponents = oldArgs.extraComponents or [] ++ extraComponents;
|
||||
extraPackages = ps: (oldArgs.extraPackages or (_: []) ps)
|
||||
++ (cfg.extraPackages ps)
|
||||
++ (lib.concatMap (component: component.propagatedBuildInputs or []) cfg.customComponents);
|
||||
++ (concatMap (component: component.propagatedBuildInputs or []) cfg.customComponents);
|
||||
}));
|
||||
|
||||
# Create a directory that holds all lovelace modules
|
||||
@@ -93,7 +126,7 @@ in {
|
||||
|
||||
meta = {
|
||||
buildDocsInSandbox = false;
|
||||
maintainers = teams.home-assistant.members;
|
||||
maintainers = lib.teams.home-assistant.members;
|
||||
};
|
||||
|
||||
options.services.home-assistant = {
|
||||
@@ -101,6 +134,15 @@ in {
|
||||
# https://github.com/home-assistant/architecture/blob/master/adr/0012-define-supported-installation-method.md#decision
|
||||
enable = mkEnableOption "Home Assistant. Please note that this installation method is unsupported upstream";
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--debug" ];
|
||||
description = ''
|
||||
Extra arguments to pass to the hass executable.
|
||||
'';
|
||||
};
|
||||
|
||||
configDir = mkOption {
|
||||
default = "/var/lib/hass";
|
||||
type = types.path;
|
||||
@@ -471,12 +513,12 @@ in {
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.config.http.server_port ];
|
||||
|
||||
# symlink the configuration to /etc/home-assistant
|
||||
environment.etc = lib.mkMerge [
|
||||
(lib.mkIf (cfg.config != null && !cfg.configWritable) {
|
||||
environment.etc = mkMerge [
|
||||
(mkIf (cfg.config != null && !cfg.configWritable) {
|
||||
"home-assistant/configuration.yaml".source = configFile;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.lovelaceConfig != null && !cfg.lovelaceConfigWritable) {
|
||||
(mkIf (cfg.lovelaceConfig != null && !cfg.lovelaceConfigWritable) {
|
||||
"home-assistant/ui-lovelace.yaml".source = lovelaceConfigFile;
|
||||
})
|
||||
];
|
||||
@@ -491,8 +533,8 @@ in {
|
||||
"mysql.service"
|
||||
"postgresql.service"
|
||||
];
|
||||
reloadTriggers = lib.optional (cfg.config != null) configFile
|
||||
++ lib.optional (cfg.lovelaceConfig != null) lovelaceConfigFile;
|
||||
reloadTriggers = optionals (cfg.config != null) [ configFile ]
|
||||
++ optionals (cfg.lovelaceConfig != null) [ lovelaceConfigFile ];
|
||||
|
||||
preStart = let
|
||||
copyConfig = if cfg.configWritable then ''
|
||||
@@ -541,20 +583,20 @@ in {
|
||||
environment.PYTHONPATH = package.pythonPath;
|
||||
serviceConfig = let
|
||||
# List of capabilities to equip home-assistant with, depending on configured components
|
||||
capabilities = lib.unique ([
|
||||
capabilities = unique ([
|
||||
# Empty string first, so we will never accidentally have an empty capability bounding set
|
||||
# https://github.com/NixOS/nixpkgs/issues/120617#issuecomment-830685115
|
||||
""
|
||||
] ++ lib.optionals (builtins.any useComponent componentsUsingBluetooth) [
|
||||
] ++ optionals (any useComponent componentsUsingBluetooth) [
|
||||
# Required for interaction with hci devices and bluetooth sockets, identified by bluetooth-adapters dependency
|
||||
# https://www.home-assistant.io/integrations/bluetooth_le_tracker/#rootless-setup-on-core-installs
|
||||
"CAP_NET_ADMIN"
|
||||
"CAP_NET_RAW"
|
||||
] ++ lib.optionals (useComponent "emulated_hue") [
|
||||
] ++ optionals (useComponent "emulated_hue") [
|
||||
# Alexa looks for the service on port 80
|
||||
# https://www.home-assistant.io/integrations/emulated_hue
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
] ++ lib.optionals (useComponent "nmap_tracker") [
|
||||
] ++ optionals (useComponent "nmap_tracker") [
|
||||
# https://www.home-assistant.io/integrations/nmap_tracker#linux-capabilities
|
||||
"CAP_NET_ADMIN"
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
@@ -582,12 +624,14 @@ in {
|
||||
"inkbird"
|
||||
"improv_ble"
|
||||
"keymitt_ble"
|
||||
"leaone-ble"
|
||||
"ld2410_ble"
|
||||
"leaone"
|
||||
"led_ble"
|
||||
"medcom_ble"
|
||||
"melnor"
|
||||
"moat"
|
||||
"mopeka"
|
||||
"motionblinds_ble"
|
||||
"oralb"
|
||||
"private_ble_device"
|
||||
"qingping"
|
||||
@@ -621,25 +665,34 @@ in {
|
||||
# mostly the ones using config flows already.
|
||||
"acer_projector"
|
||||
"alarmdecoder"
|
||||
"aurora_abb_powerone"
|
||||
"blackbird"
|
||||
"bryant_evolution"
|
||||
"crownstone"
|
||||
"deconz"
|
||||
"dsmr"
|
||||
"edl21"
|
||||
"elkm1"
|
||||
"elv"
|
||||
"enocean"
|
||||
"homeassistant_hardware"
|
||||
"homeassistant_yellow"
|
||||
"firmata"
|
||||
"flexit"
|
||||
"gpsd"
|
||||
"insteon"
|
||||
"kwb"
|
||||
"lacrosse"
|
||||
"landisgyr_heat_meter"
|
||||
"modbus"
|
||||
"modem_callerid"
|
||||
"mysensors"
|
||||
"nad"
|
||||
"numato"
|
||||
"nut"
|
||||
"opentherm_gw"
|
||||
"otbr"
|
||||
"rainforst_raven"
|
||||
"rflink"
|
||||
"rfxtrx"
|
||||
"scsgate"
|
||||
@@ -655,12 +708,21 @@ in {
|
||||
"zwave_js"
|
||||
];
|
||||
in {
|
||||
ExecStart = "${package}/bin/hass --config '${cfg.configDir}'";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
ExecStart = escapeSystemdExecArgs ([
|
||||
(lib.getExe package)
|
||||
"--config" cfg.configDir
|
||||
] ++ cfg.extraArgs);
|
||||
ExecReload = (escapeSystemdExecArgs [
|
||||
(lib.getExe' pkgs.coreutils "kill")
|
||||
"-HUP"
|
||||
]) + " $MAINPID";
|
||||
User = "hass";
|
||||
Group = "hass";
|
||||
WorkingDirectory = cfg.configDir;
|
||||
Restart = "on-failure";
|
||||
|
||||
# Signal handling
|
||||
# homeassistant/helpers/signal.py
|
||||
RestartForceExitStatus = "100";
|
||||
SuccessExitStatus = "100";
|
||||
KillSignal = "SIGINT";
|
||||
|
||||
@@ -456,7 +456,7 @@ in {
|
||||
hitch = handleTest ./hitch {};
|
||||
hledger-web = handleTest ./hledger-web.nix {};
|
||||
hockeypuck = handleTest ./hockeypuck.nix { };
|
||||
home-assistant = handleTest ./home-assistant.nix {};
|
||||
home-assistant = runTest ./home-assistant.nix;
|
||||
hostname = handleTest ./hostname.nix {};
|
||||
hound = handleTest ./hound.nix {};
|
||||
hub = handleTest ./git/hub.nix {};
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||
{
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
configDir = "/var/lib/foobar";
|
||||
@@ -122,7 +125,7 @@ in {
|
||||
# Cause a configuration change that requires a service restart as we added a new runtime dependency
|
||||
specialisation.newFeature = {
|
||||
inheritParentConfig = true;
|
||||
configuration.services.home-assistant.config.backup = {};
|
||||
configuration.services.home-assistant.config.prometheus = {};
|
||||
};
|
||||
|
||||
specialisation.removeCustomThings = {
|
||||
@@ -206,25 +209,25 @@ in {
|
||||
with subtest("Check extra components are considered in systemd unit hardening"):
|
||||
hass.succeed("systemctl show -p DeviceAllow home-assistant.service | grep -q char-ttyUSB")
|
||||
|
||||
with subtest("Check service reloads when configuration changes"):
|
||||
with subtest("Check service restart from SIGHUP"):
|
||||
pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
cursor = get_journal_cursor()
|
||||
hass.succeed("${system}/specialisation/differentName/bin/switch-to-configuration test")
|
||||
new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
assert pid == new_pid, "The PID of the process should not change between process reloads"
|
||||
wait_for_homeassistant(cursor)
|
||||
new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
assert pid != new_pid, "The PID of the process must change after sending SIGHUP"
|
||||
|
||||
with subtest("Check service restarts when dependencies change"):
|
||||
pid = new_pid
|
||||
cursor = get_journal_cursor()
|
||||
hass.succeed("${system}/specialisation/newFeature/bin/switch-to-configuration test")
|
||||
new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
assert pid != new_pid, "The PID of the process should change when its PYTHONPATH changess"
|
||||
wait_for_homeassistant(cursor)
|
||||
new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
assert pid != new_pid, "The PID of the process must change when its PYTHONPATH changess"
|
||||
|
||||
with subtest("Check that new components get setup after restart"):
|
||||
journal = get_journal_since(cursor)
|
||||
for domain in ["backup"]:
|
||||
for domain in ["prometheus"]:
|
||||
assert f"Setup of domain {domain} took" in journal, f"{domain} setup missing"
|
||||
|
||||
with subtest("Check custom components and custom lovelace modules get removed"):
|
||||
@@ -242,4 +245,4 @@ in {
|
||||
hass.log(hass.succeed("systemctl cat home-assistant.service"))
|
||||
hass.log(hass.succeed("systemd-analyze security home-assistant.service"))
|
||||
'';
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user