From c0330351a06ffebc70e4bbcfe9bad43449aab4b7 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Mon, 26 Feb 2024 12:00:01 +0000 Subject: nixos/homepage-dashboard: support structured config --- nixos/modules/services/misc/homepage-dashboard.nix | 224 +++++++++++++++++++-- 1 file changed, 206 insertions(+), 18 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/services/misc/homepage-dashboard.nix b/nixos/modules/services/misc/homepage-dashboard.nix index 07a09e2b6bbf5..02f1378cb0d59 100644 --- a/nixos/modules/services/misc/homepage-dashboard.nix +++ b/nixos/modules/services/misc/homepage-dashboard.nix @@ -6,6 +6,8 @@ let cfg = config.services.homepage-dashboard; + # Define the settings format used for this program + settingsFormat = pkgs.formats.yaml { }; in { options = { @@ -25,31 +27,217 @@ in default = 8082; description = lib.mdDoc "Port for Homepage to bind to."; }; + + environmentFile = lib.mkOption { + type = lib.types.str; + description = '' + The path to an environment file that contains environment variables to pass + to the homepage-dashboard service, for the purpose of passing secrets to + the service. + + See the upstream documentation: + + https://gethomepage.dev/latest/installation/docker/#using-environment-secrets + ''; + default = ""; + }; + + customCSS = lib.mkOption { + type = lib.types.lines; + description = lib.mdDoc '' + Custom CSS for styling Homepage. + + See https://gethomepage.dev/latest/configs/custom-css-js/. + ''; + default = ""; + }; + + customJS = lib.mkOption { + type = lib.types.lines; + description = lib.mdDoc '' + Custom Javascript for Homepage. + + See https://gethomepage.dev/latest/configs/custom-css-js/. + ''; + default = ""; + }; + + bookmarks = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage bookmarks configuration. + + See https://gethomepage.dev/latest/configs/bookmarks/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/bookmarks.yaml + example = [ + { + Developer = [ + { Github = [{ abbr = "GH"; href = "https://github.com/"; }]; } + ]; + } + { + Entertainment = [ + { YouTube = [{ abbr = "YT"; href = "https://youtube.com/"; }]; } + ]; + } + ]; + default = [ ]; + }; + + services = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage services configuration. + + See https://gethomepage.dev/latest/configs/services/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/services.yaml + example = [ + { + "My First Group" = [ + { + "My First Service" = { + href = "http://localhost/"; + description = "Homepage is awesome"; + }; + } + ]; + } + { + "My Second Group" = [ + { + "My Second Service" = { + href = "http://localhost/"; + description = "Homepage is the best"; + }; + } + ]; + } + ]; + default = [ ]; + }; + + widgets = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage widgets configuration. + + See https://gethomepage.dev/latest/configs/service-widgets/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/widgets.yaml + example = [ + { + resources = { + cpu = true; + memory = true; + disk = "/"; + }; + } + { + search = { + provider = "duckduckgo"; + target = "_blank"; + }; + } + ]; + default = [ ]; + }; + + kubernetes = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage kubernetes configuration. + + See https://gethomepage.dev/latest/configs/kubernetes/. + ''; + default = { }; + }; + + docker = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage docker configuration. + + See https://gethomepage.dev/latest/configs/docker/. + ''; + default = { }; + }; + + settings = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage settings. + + See https://gethomepage.dev/latest/configs/settings/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml + default = { }; + }; }; }; - config = lib.mkIf cfg.enable { - systemd.services.homepage-dashboard = { - description = "Homepage Dashboard"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; + config = + let + # If homepage-dashboard is enabled, but none of the configuration values have been updated, + # then default to "unmanaged" configuration which is manually updated in + # var/lib/homepage-dashboard. This is to maintain backwards compatibility, and should be + # deprecated in a future release. + managedConfig = !( + cfg.bookmarks == [ ] && + cfg.customCSS == "" && + cfg.customJS == "" && + cfg.docker == { } && + cfg.kubernetes == { } && + cfg.services == [ ] && + cfg.settings == { } && + cfg.widgets == [ ] + ); + + configDir = if managedConfig then "/etc/homepage-dashboard" else "/var/lib/homepage-dashboard"; + + msg = "using unmanaged configuration for homepage-dashboard is deprecated and will be removed" + + " in 24.05. please see the NixOS documentation for `services.homepage-dashboard' and add" + + " your bookmarks, services, widgets, and other configuration using the options provided."; + in + lib.mkIf cfg.enable { + warnings = lib.optional (!managedConfig) msg; - environment = { - HOMEPAGE_CONFIG_DIR = "/var/lib/homepage-dashboard"; - PORT = "${toString cfg.listenPort}"; + environment.etc = lib.mkIf managedConfig { + "homepage-dashboard/custom.css".text = cfg.customCSS; + "homepage-dashboard/custom.js".text = cfg.customJS; + + "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks; + "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker; + "homepage-dashboard/kubernetes.yaml".source = settingsFormat.generate "kubernetes.yaml" cfg.kubernetes; + "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services; + "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings; + "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets; }; - serviceConfig = { - Type = "simple"; - DynamicUser = true; - StateDirectory = "homepage-dashboard"; - ExecStart = "${lib.getExe cfg.package}"; - Restart = "on-failure"; + systemd.services.homepage-dashboard = { + description = "Homepage Dashboard"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + HOMEPAGE_CONFIG_DIR = configDir; + PORT = toString cfg.listenPort; + LOG_TARGETS = lib.mkIf managedConfig "stdout"; + }; + + serviceConfig = { + Type = "simple"; + DynamicUser = true; + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; + StateDirectory = lib.mkIf (!managedConfig) "homepage-dashboard"; + ExecStart = lib.getExe cfg.package; + Restart = "on-failure"; + }; }; - }; - networking.firewall = lib.mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.listenPort ]; + networking.firewall = lib.mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.listenPort ]; + }; }; - }; } -- cgit 1.4.1 From 183bc82cca1e3175cc3bfda91fb2525bb3b88c05 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Mon, 26 Feb 2024 18:03:28 +0000 Subject: nixos/homepage-dashboard: add breaking change notice to release notes --- nixos/doc/manual/release-notes/rl-2405.section.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nixos') diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index b5973c19a2c4b..08cba1790ca2f 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -134,6 +134,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`. +- `services.homepage-dashboard` now takes it's configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix. + - The legacy and long deprecated systemd target `network-interfaces.target` has been removed. Use `network.target` instead. - `services.frp.settings` now generates the frp configuration file in TOML format as [recommended by upstream](https://github.com/fatedier/frp#configuration-files), instead of the legacy INI format. This has also introduced other changes in the configuration file structure and options. -- cgit 1.4.1 From 0b39e86cbc509bbe7d6e0a5c10f4860e68483e53 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Sun, 3 Mar 2024 18:07:28 +0000 Subject: nixosTests.homepage-dashboard: test managed and unmanaged configs --- nixos/tests/homepage-dashboard.nix | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'nixos') diff --git a/nixos/tests/homepage-dashboard.nix b/nixos/tests/homepage-dashboard.nix index 56e077f5ff6de..dd36473e8ac02 100644 --- a/nixos/tests/homepage-dashboard.nix +++ b/nixos/tests/homepage-dashboard.nix @@ -2,13 +2,35 @@ import ./make-test-python.nix ({ lib, ... }: { name = "homepage-dashboard"; meta.maintainers = with lib.maintainers; [ jnsgruk ]; - nodes.machine = { pkgs, ... }: { + nodes.unmanaged_conf = { pkgs, ... }: { services.homepage-dashboard.enable = true; }; + nodes.managed_conf = { pkgs, ... }: { + services.homepage-dashboard = { + enable = true; + settings.title = "custom"; + }; + }; + testScript = '' - machine.wait_for_unit("homepage-dashboard.service") - machine.wait_for_open_port(8082) - machine.succeed("curl --fail http://localhost:8082/") + # Ensure the services are started on unmanaged machine + unmanaged_conf.wait_for_unit("homepage-dashboard.service") + unmanaged_conf.wait_for_open_port(8082) + unmanaged_conf.succeed("curl --fail http://localhost:8082/") + + # Ensure that /etc/homepage-dashboard doesn't exist, and boilerplate + # configs are copied into place. + unmanaged_conf.fail("test -d /etc/homepage-dashboard") + unmanaged_conf.succeed("test -f /var/lib/private/homepage-dashboard/settings.yaml") + + # Ensure the services are started on managed machine + managed_conf.wait_for_unit("homepage-dashboard.service") + managed_conf.wait_for_open_port(8082) + managed_conf.succeed("curl --fail http://localhost:8082/") + + # Ensure /etc/homepage-dashboard is created and unmanaged conf location isn't. + managed_conf.succeed("test -d /etc/homepage-dashboard") + managed_conf.fail("test -f /var/lib/private/homepage-dashboard/settings.yaml") ''; }) -- cgit 1.4.1