mirror of
https://github.com/CHN-beta/nixpkgs.git
synced 2026-01-12 02:40:31 +08:00
nixos/home-assistant: declarative blueprints
This commit is contained in:
@@ -408,6 +408,8 @@
|
||||
|
||||
- `services.avahi.ipv6` now defaults to true.
|
||||
|
||||
- The Home Assistant module has new options {option}`services.home-assistant.blueprints.automation`, `services.home-assistant.blueprints.script`, and {option}`services.home-assistant.blueprints.template` that allow for the declarative installation of [blueprints](https://www.home-assistant.io/docs/blueprint/) into the appropriate configuration directories.
|
||||
|
||||
- For matrix homeserver Synapse we are now following the upstream recommendation to enable jemalloc as the memory allocator by default.
|
||||
|
||||
- `services.kmonad` now creates a determinate symlink (in `/dev/input/by-id/`) to each of KMonad virtual devices.
|
||||
|
||||
@@ -6,17 +6,22 @@ let
|
||||
attrByPath
|
||||
attrValues
|
||||
concatMap
|
||||
concatStrings
|
||||
converge
|
||||
elem
|
||||
escapeShellArg
|
||||
escapeShellArgs
|
||||
filter
|
||||
filterAttrsRecursive
|
||||
flatten
|
||||
hasAttrByPath
|
||||
isAttrs
|
||||
isDerivation
|
||||
isList
|
||||
isStorePath
|
||||
literalExpression
|
||||
mapAttrsToList
|
||||
mergeAttrsList
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
@@ -28,6 +33,7 @@ let
|
||||
recursiveUpdate
|
||||
singleton
|
||||
splitString
|
||||
substring
|
||||
types
|
||||
unique
|
||||
;
|
||||
@@ -502,6 +508,41 @@ in {
|
||||
type = types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
|
||||
blueprints = mergeAttrsList (
|
||||
map
|
||||
(domain: {
|
||||
${domain} = mkOption {
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of ${domain}
|
||||
[blueprints](https://www.home-assistant.io/docs/blueprint/) to
|
||||
install into {file}`''${configDir}/blueprints/${domain}`.
|
||||
'';
|
||||
example =
|
||||
if domain == "automation" then
|
||||
literalExpression ''
|
||||
[
|
||||
(pkgs.fetchurl {
|
||||
url = "https://github.com/home-assistant/core/raw/2025.1.4/homeassistant/components/automation/blueprints/motion_light.yaml";
|
||||
hash = "sha256-4HrDX65ycBMfEY2nZ7A25/d3ZnIHdpHZ+80Cblp+P5w=";
|
||||
})
|
||||
]
|
||||
''
|
||||
else if domain == "template" then
|
||||
literalExpression "[ \"\${pkgs.home-assistant.src}/homeassistant/components/template/blueprints/inverted_binary_sensor.yaml\" ]"
|
||||
else
|
||||
literalExpression "[ ./blueprint.yaml ]";
|
||||
type = types.listOf (types.coercedTo types.path (x: "${x}") types.pathInStore);
|
||||
};
|
||||
})
|
||||
# https://www.home-assistant.io/docs/blueprint/schema/#domain
|
||||
[
|
||||
"automation"
|
||||
"script"
|
||||
"template"
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
@@ -576,11 +617,36 @@ in {
|
||||
ln -fns "''${paths[@]}" "${cfg.configDir}/custom_components/"
|
||||
done
|
||||
'';
|
||||
removeBlueprints = ''
|
||||
# remove blueprints symlinked in from below the /nix/store
|
||||
readarray -d "" blueprints < <(find "${cfg.configDir}/blueprints" -maxdepth 2 -type l -print0)
|
||||
for blueprint in "''${blueprints[@]}"; do
|
||||
if [[ "$(readlink "$blueprint")" =~ ^${escapeShellArg builtins.storeDir} ]]; then
|
||||
rm "$blueprint"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
copyBlueprint =
|
||||
domain: blueprint:
|
||||
let
|
||||
filename =
|
||||
if isStorePath blueprint then substring 33 (-1) (baseNameOf blueprint) else baseNameOf blueprint;
|
||||
path = "${cfg.configDir}/blueprints/${domain}";
|
||||
in
|
||||
''
|
||||
mkdir -p ${escapeShellArg path}
|
||||
ln -s ${escapeShellArg blueprint} ${escapeShellArg "${path}/${filename}"}
|
||||
'';
|
||||
copyBlueprints = concatStrings (
|
||||
flatten (mapAttrsToList (domain: map (copyBlueprint domain)) cfg.blueprints)
|
||||
);
|
||||
in
|
||||
(optionalString (cfg.config != null) copyConfig) +
|
||||
(optionalString (cfg.lovelaceConfig != null) copyLovelaceConfig) +
|
||||
copyCustomLovelaceModules +
|
||||
copyCustomComponents
|
||||
copyCustomComponents +
|
||||
removeBlueprints +
|
||||
copyBlueprints
|
||||
;
|
||||
environment.PYTHONPATH = package.pythonPath;
|
||||
serviceConfig = let
|
||||
|
||||
@@ -129,6 +129,16 @@ in
|
||||
];
|
||||
};
|
||||
lovelaceConfigWritable = true;
|
||||
|
||||
blueprints.automation = [
|
||||
(pkgs.fetchurl {
|
||||
url = "https://github.com/home-assistant/core/raw/2025.1.4/homeassistant/components/automation/blueprints/motion_light.yaml";
|
||||
hash = "sha256-4HrDX65ycBMfEY2nZ7A25/d3ZnIHdpHZ+80Cblp+P5w=";
|
||||
})
|
||||
];
|
||||
blueprints.template = [
|
||||
"${pkgs.home-assistant.src}/homeassistant/components/template/blueprints/inverted_binary_sensor.yaml"
|
||||
];
|
||||
};
|
||||
|
||||
# Cause a configuration change inside `configuration.yml` and verify that the process is being reloaded.
|
||||
@@ -148,6 +158,8 @@ in
|
||||
configuration.services.home-assistant = {
|
||||
customComponents = lib.mkForce [ ];
|
||||
customLovelaceModules = lib.mkForce [ ];
|
||||
blueprints.automation = lib.mkForce [ ];
|
||||
blueprints.template = lib.mkForce [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -226,6 +238,10 @@ 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 that blueprints are installed"):
|
||||
hass.succeed("test -L '${configDir}/blueprints/automation/motion_light.yaml'")
|
||||
hass.succeed("test -L '${configDir}/blueprints/template/inverted_binary_sensor.yaml'")
|
||||
|
||||
with subtest("Check service restart from SIGHUP"):
|
||||
pid = hass.succeed("systemctl show --property=MainPID home-assistant.service")
|
||||
cursor = get_journal_cursor()
|
||||
@@ -247,12 +263,14 @@ in
|
||||
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"):
|
||||
with subtest("Check custom components, custom lovelace modules, and blueprints get removed"):
|
||||
cursor = get_journal_cursor()
|
||||
hass.succeed("${system}/specialisation/removeCustomThings/bin/switch-to-configuration test")
|
||||
hass.fail("grep -q 'mini-graph-card-bundle.js' '${configDir}/ui-lovelace.yaml'")
|
||||
for integration in ("prometheus_sensor", "spook", "spook_inverse"):
|
||||
hass.fail(f"test -f ${configDir}/custom_components/{integration}/manifest.json")
|
||||
hass.fail("test -e '${configDir}/blueprints/automation/motion_light.yaml'")
|
||||
hass.fail("test -e '${configDir}/blueprints/template/inverted_binary_sensor.yaml'")
|
||||
wait_for_homeassistant(cursor)
|
||||
|
||||
with subtest("Check that no errors were logged"):
|
||||
|
||||
Reference in New Issue
Block a user