From 3ce9b625d1630bccef9cf89fe70a0f0c29e21063 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Sat, 12 Jul 2025 15:00:59 -0500 Subject: [PATCH] fixed home assistant --- .../nixos/defiant/configuration.nix | 9 +- modules/nixos-modules/server/adguardhome.nix | 2 +- modules/nixos-modules/server/default.nix | 2 +- .../nixos-modules/server/home-assistant.nix | 220 +++++++++--------- modules/nixos-modules/server/podman.nix | 2 +- .../server/virt-home-assistant.nix | 155 ------------ 6 files changed, 122 insertions(+), 268 deletions(-) delete mode 100644 modules/nixos-modules/server/virt-home-assistant.nix diff --git a/configurations/nixos/defiant/configuration.nix b/configurations/nixos/defiant/configuration.nix index 7d9c6d8..9824e56 100644 --- a/configurations/nixos/defiant/configuration.nix +++ b/configurations/nixos/defiant/configuration.nix @@ -282,10 +282,11 @@ subdomain = "search"; }; - virt-home-assistant = { - enable = false; - networkBridge = "bond0"; - hostDevice = "0x10c4:0xea60"; + home-assistant = { + enable = true; + subdomain = "home"; + openFirewall = true; + database = "postgres"; }; qbittorrent = { diff --git a/modules/nixos-modules/server/adguardhome.nix b/modules/nixos-modules/server/adguardhome.nix index 866ad8a..abd1254 100644 --- a/modules/nixos-modules/server/adguardhome.nix +++ b/modules/nixos-modules/server/adguardhome.nix @@ -6,7 +6,7 @@ dnsPort = 53; in { options.host.adguardhome = { - enable = lib.mkEnableOption "should home-assistant be enabled on this computer"; + enable = lib.mkEnableOption "should ad guard home be enabled on this computer"; directory = lib.mkOption { type = lib.types.str; default = "/var/lib/AdGuardHome/"; diff --git a/modules/nixos-modules/server/default.nix b/modules/nixos-modules/server/default.nix index 7beee8b..83a0830 100644 --- a/modules/nixos-modules/server/default.nix +++ b/modules/nixos-modules/server/default.nix @@ -8,7 +8,7 @@ ./jellyfin.nix ./forgejo.nix ./searx.nix - ./virt-home-assistant.nix + ./home-assistant.nix ./adguardhome.nix ./immich.nix ./qbittorent.nix diff --git a/modules/nixos-modules/server/home-assistant.nix b/modules/nixos-modules/server/home-assistant.nix index a90bd6d..7497995 100644 --- a/modules/nixos-modules/server/home-assistant.nix +++ b/modules/nixos-modules/server/home-assistant.nix @@ -1,130 +1,138 @@ { lib, config, - inputs, ... }: let configDir = "/var/lib/hass"; + dbUser = "hass"; in { - options.host.home-assistant = { - enable = lib.mkEnableOption "should home-assistant be enabled on this computer"; + options.services.home-assistant = { subdomain = lib.mkOption { type = lib.types.str; description = "subdomain of base domain that home-assistant will be hosted at"; default = "home-assistant"; }; + + database = lib.mkOption { + type = lib.types.enum [ + "builtin" + "postgres" + ]; + description = "what database do we want to use"; + default = "builtin"; + }; }; - config = lib.mkIf config.host.home-assistant.enable (lib.mkMerge [ + config = lib.mkIf config.services.home-assistant.enable (lib.mkMerge [ { - virtualisation.libvirt = { - swtpm.enable = true; - connections."qemu:///session" = { - networks = [ - { - definition = inputs.nix-virt.lib.network.writeXML (inputs.nix-virt.lib.network.templates.bridge - { - uuid = "d57e37e2-311f-4e5c-a484-97c2210c2770"; - subnet_byte = 71; - }); - active = true; - } - ]; - domains = [ - { - definition = inputs.nix-virt.lib.domain.writeXML (inputs.nix-virt.lib.domain.templates.linux - { - name = "Home Assistant"; - uuid = "c5cc0efc-6101-4c1d-be31-acbba203ccde"; - memory = { - count = 4; - unit = "GiB"; - }; - # storage_vol = { - # pool = "MyPool"; - # volume = "Penguin.qcow2"; - # }; - }); - } - ]; + host = { + reverse_proxy.subdomains.${config.services.home-assistant.subdomain} = { + target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; + + websockets.enable = true; + forwardHeaders.enable = true; + + extraConfig = '' + add_header Upgrade $http_upgrade; + add_header Connection \"upgrade\"; + + proxy_buffering off; + + proxy_read_timeout 90; + ''; }; }; - # systemd.tmpfiles.rules = [ - # "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" - # ]; - # services.home-assistant = { - # enable = true; - # configDir = configDir; - # extraComponents = [ - # "met" - # "radio_browser" - # "isal" - # "zha" - # "jellyfin" - # "webostv" - # "tailscale" - # "syncthing" - # "sonos" - # "analytics_insights" - # "unifi" - # "openweathermap" - # ]; - # config = { - # http = { - # server_port = 8082; - # use_x_forwarded_for = true; - # trusted_proxies = ["127.0.0.1" "::1"]; - # ip_ban_enabled = true; - # login_attempts_threshold = 10; - # }; - # # recorder.db_url = "postgresql://@/${db_user}"; - # "automation manual" = []; - # "automation ui" = "!include automations.yaml"; - # }; - # extraPackages = python3Packages: - # with python3Packages; [ - # hassil - # numpy - # gtts - # ]; - # }; - # host = { - # reverse_proxy.subdomains.${config.host.home-assistant.subdomain} = { - # target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; + services.home-assistant = { + configDir = configDir; + extraComponents = [ + "met" + "radio_browser" + "isal" + "zha" + "jellyfin" + "webostv" + "tailscale" + "syncthing" + "sonos" + "analytics_insights" + "unifi" + "openweathermap" + "ollama" + ]; + config = { + http = { + server_port = 8123; + use_x_forwarded_for = true; + trusted_proxies = ["127.0.0.1" "::1"]; + ip_ban_enabled = true; + login_attempts_threshold = 10; + }; + recorder.db_url = "postgresql://@/${dbUser}"; + "automation manual" = []; + "automation ui" = "!include automations.yaml"; + }; + extraPackages = python3Packages: + with python3Packages; [ + hassil + numpy + gtts + ]; + }; - # websockets.enable = true; - # forwardHeaders.enable = true; - - # extraConfig = '' - # add_header Upgrade $http_upgrade; - # add_header Connection \"upgrade\"; - - # proxy_buffering off; - - # proxy_read_timeout 90; - # ''; - # }; - # }; + systemd.tmpfiles.rules = [ + "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" + ]; } + (lib.mkIf (config.services.home-assistant.database == "postgres") { + host = { + postgres = { + enable = true; + extraUsers = { + ${dbUser} = { + isClient = true; + createUser = true; + }; + }; + extraDatabases = { + ${dbUser} = { + name = dbUser; + }; + }; + }; + }; + + services.home-assistant = { + extraPackages = python3Packages: + with python3Packages; [ + psycopg2 + ]; + }; + + systemd.services.home-assistant = { + requires = [ + config.systemd.services.postgresql.name + ]; + }; + }) (lib.mkIf config.host.impermanence.enable { - # assertions = [ - # { - # assertion = config.services.home-assistant.configDir == configDir; - # message = "home assistant config directory does not match persistence"; - # } - # ]; - # environment.persistence."/persist/system/root" = { - # enable = true; - # hideMounts = true; - # directories = [ - # { - # directory = configDir; - # user = "hass"; - # group = "hass"; - # } - # ]; - # }; + assertions = [ + { + assertion = config.services.home-assistant.configDir == configDir; + message = "home assistant config directory does not match persistence"; + } + ]; + environment.persistence."/persist/system/root" = { + enable = true; + hideMounts = true; + directories = [ + { + directory = configDir; + user = "hass"; + group = "hass"; + } + ]; + }; }) ]); } diff --git a/modules/nixos-modules/server/podman.nix b/modules/nixos-modules/server/podman.nix index e806e65..9301140 100644 --- a/modules/nixos-modules/server/podman.nix +++ b/modules/nixos-modules/server/podman.nix @@ -4,7 +4,7 @@ ... }: { options.host.podman = { - enable = lib.mkEnableOption "should home-assistant be enabled on this computer"; + enable = lib.mkEnableOption "should podman be enabled on this computer"; macvlan = { subnet = lib.mkOption { type = lib.types.str; diff --git a/modules/nixos-modules/server/virt-home-assistant.nix b/modules/nixos-modules/server/virt-home-assistant.nix deleted file mode 100644 index 4212668..0000000 --- a/modules/nixos-modules/server/virt-home-assistant.nix +++ /dev/null @@ -1,155 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: { - options.services.virt-home-assistant = { - enable = lib.mkEnableOption "Wether to enable home assistant virtual machine"; - networkBridge = lib.mkOption { - type = lib.types.str; - description = "what network bridge should we attach to the image"; - }; - hostDevice = lib.mkOption { - type = lib.types.str; - description = "what host devices should be attached to the image"; - }; - initialVersion = lib.mkOption { - type = lib.types.str; - description = "what home assistant image version should we pull for initial instal"; - default = "15.0"; - }; - imageName = lib.mkOption { - type = lib.types.str; - description = "where should the image be installed to"; - default = "home-assistant.qcow2"; - }; - installLocation = lib.mkOption { - type = lib.types.str; - description = "where should the image be installed to"; - default = "/etc/hass"; - }; - virtualMachineName = lib.mkOption { - type = lib.types.str; - description = "what name should we give the virtual machine"; - default = "home-assistant"; - }; - subdomain = lib.mkOption { - type = lib.types.str; - description = "subdomain of base domain that home-assistant will be hosted at"; - default = "home-assistant"; - }; - }; - config = lib.mkIf config.services.virt-home-assistant.enable (lib.mkMerge [ - { - # environment.systemPackages = with pkgs; [ - # virt-manager - # ]; - - # TODO: move this to external module and just have an assertion here that its enabled - # enable virtualization on the system - virtualisation = { - libvirtd = { - enable = true; - qemu.ovmf.enable = true; - }; - }; - - # TODO: deactivation script? - # create service to install and start the container - systemd.services.virt-install-home-assistant = let - # TODO: all of these need to be escaped to be used in commands reliably - bridgedNetwork = config.services.virt-home-assistant.networkBridge; - hostDevice = config.services.virt-home-assistant.hostDevice; - virtualMachineName = config.services.virt-home-assistant.virtualMachineName; - imageName = config.services.virt-home-assistant.imageName; - installLocation = config.services.virt-home-assistant.installLocation; - installImage = "${installLocation}/${imageName}"; - initialVersion = config.services.virt-home-assistant.initialVersion; - - home-assistant-qcow2 = pkgs.fetchurl { - name = "home-assistant.qcow2"; - url = "https://github.com/home-assistant/operating-system/releases/download/${initialVersion}/haos_ova-${initialVersion}.qcow2.xz"; - hash = "sha256-V1BEjvvLNbMMKJVyMCmipjQ/3owoJteeVxoF9LDHo1U="; - postFetch = '' - cp $out src.xz - rm -r $out - ${pkgs.xz}/bin/unxz src.xz --stdout > $out/${imageName} - ''; - }; - - # Write a script to install the Home Assistant OS qcow2 image - virtInstallScript = pkgs.writeShellScriptBin "virt-install-hass" '' - # Copy the initial image out of the package store to the install location if we don't have one yet - if [ ! -f ${installImage} ]; then - cp ${home-assistant-qcow2} ${installLocation} - fi - - # Check if VM already exists, and other pre-conditions - if ! ${pkgs.libvirt}/bin/virsh list --all | grep -q ${virtualMachineName}; then - ${pkgs.virt-manager}/bin/virt-install --name ${virtualMachineName} \ - --description "Home Assistant OS" \ - --os-variant=generic \ - --boot uefi \ - --ram=2048 \ - --vcpus=2 \ - --import \ - --disk ${installImage},bus=sata \ - --network bridge=${bridgedNetwork} \ - --host-device ${hostDevice} \ - --graphics none - ${pkgs.libvirt}/bin/virsh autostart ${virtualMachineName} - fi - ''; - in { - description = "Install and start Home Assistant"; - wantedBy = ["multi-user.target"]; - after = ["local-fs.target"]; - requires = ["libvirtd.service"]; - serviceConfig.Type = "oneshot"; - serviceConfig = { - ExecStart = "${virtInstallScript}/bin/virt-install-hass"; - }; - }; - - # TODO: figure out what we need to proxy to the virtual image - # host = { - # reverse_proxy.subdomains.${config.services.virt-home-assistant.subdomain} = { - # target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; - - # websockets.enable = true; - # forwardHeaders.enable = true; - - # extraConfig = '' - # add_header Upgrade $http_upgrade; - # add_header Connection \"upgrade\"; - - # proxy_buffering off; - - # proxy_read_timeout 90; - # ''; - # }; - # }; - } - (lib.mkIf config.services.fail2ban.enable { - # TODO: figure out how to write a config for this, prob based on nginx proxy logs? - }) - (lib.mkIf config.host.impermanence.enable { - # assertions = [ - # { - # assertion = config.services.virt-home-assistant.installLocation == configDir; - # message = "home assistant install location does not match persistence"; - # } - # ]; - environment.persistence."/persist/system/root" = { - enable = true; - hideMounts = true; - directories = [ - { - directory = config.services.virt-home-assistant.installLocation; - } - ]; - }; - }) - ]); -}