From fe162968e5b4efa33c0b4d47d08cb3eeff5f7138 Mon Sep 17 00:00:00 2001 From: Lucas Bergman Date: Mon, 19 Feb 2024 20:31:47 -0600 Subject: [PATCH 1/4] maint: Run nix stuff through the formatter There are several choices for formatting Nix code, but IMHO alejandra is the right kind of opinionated: . --- default.nix | 19 ++-- flake.nix | 270 ++++++++++++++++++++++++++++------------------------ 2 files changed, 153 insertions(+), 136 deletions(-) diff --git a/default.nix b/default.nix index 79038c8..7d85ea6 100644 --- a/default.nix +++ b/default.nix @@ -1,11 +1,12 @@ let - lock = builtins.fromJSON (builtins.readFile ./flake.lock); + lock = builtins.fromJSON (builtins.readFile ./flake.lock); in -(import ( - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; - sha256 = lock.nodes.flake-compat.locked.narHash; - } -) { - src = ./.; -}).defaultNix + (import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) { + src = ./.; + }) + .defaultNix diff --git a/flake.nix b/flake.nix index bce900c..09901b3 100644 --- a/flake.nix +++ b/flake.nix @@ -6,147 +6,163 @@ inputs.nixpkgs.follows = "nixpkgs"; }; naersk.url = "github:nix-community/naersk"; - flake-compat = { url = github:edolstra/flake-compat; flake = false; }; - flake-utils.url = "github:numtide/flake-utils"; + flake-compat = { + url = github:edolstra/flake-compat; + flake = false; + }; + flake-utils.url = "github:numtide/flake-utils"; }; - - outputs = {nixpkgs, flake-utils, naersk, rust-overlay, ...}: + + outputs = { + nixpkgs, + flake-utils, + naersk, + rust-overlay, + ... + }: flake-utils.lib.eachDefaultSystem (system: let overlays = [ rust-overlay.overlays.default ]; - pkgs = import nixpkgs { inherit system overlays; }; + pkgs = import nixpkgs {inherit system overlays;}; rust-bin = pkgs.rust-bin.stable."1.71.0".default; naersk-lib = pkgs.callPackage naersk { - rustc = rust-bin; - cargo = rust-bin; + rustc = rust-bin; + cargo = rust-bin; }; heracles = naersk-lib.buildPackage { - name = "heracles"; - verion = "0.0.1"; - src = ./.; - nativeBuildInputs = [ pkgs.pkg-config ]; - buildInputs = ( - if pkgs.stdenv.isDarwin then - with pkgs.darwin.apple_sdk.frameworks; [ Security SystemConfiguration ] - else - [ pkgs.openssl ]) ++ [rust-bin]; + name = "heracles"; + verion = "0.0.1"; + src = ./.; + nativeBuildInputs = [pkgs.pkg-config]; + buildInputs = + ( + if pkgs.stdenv.isDarwin + then with pkgs.darwin.apple_sdk.frameworks; [Security SystemConfiguration] + else [pkgs.openssl] + ) + ++ [rust-bin]; }; - in - { + in { packages.default = heracles; - }) // { - nixosModule = {config, pkgs, lib}: with lib; { - options = { - services.heracles.enable = mkEnableOption "enable heracles service"; - services.heracles.listen = mkOption { - description = "[host]:port address for heracles to listen on"; - default = "localhost:8080"; - defaultText = "localhost:8080"; - }; - - services.heracles.settings = mkOption { - description = "heracles dashboard Configuration"; - default = [ - { - title = "A dashboard"; - graphs = [ - { - title = "Graph title"; - query_type = "Range"; - # yaxis formatting default for this graph - d3_tick_format = "~s"; - plots = [ - { - source = "http://heimdall:9001"; - query = '' - sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) - ''; - meta = { - name_function = "`\${labels.instance}`"; - named_axis = "y"; - # yaxis formatting for this subplot - d3_tick_format = "~s"; - }; - } - ]; - # span for this graph. - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ]; - # default span for dashboard - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ]; - defaultText = '' - [ - { - title = "A dashboard"; - graphs = [ - { - title = "Graph title"; - query_type = "Range"; - # yaxis formatting default for this graph - d3_tick_format = "~s"; - plots = [ - { - source = "http://heimdall:9001"; - query = \'\' - sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) - \'\'; - meta = { - name_label = "instance"; - name_prefix = "trace name prefix"; - name_suffix = "trace name suffix"; - named_axis = "y"; - # yaxis formatting for this subplot - d3_tick_format = "~s"; - }; - } - ]; - # span for this graph. - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ]; - # default span for dashboard - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ] - ''; - }; + }) + // { + nixosModule = { + config, + pkgs, + lib, + }: + with lib; { + options = { + services.heracles.enable = mkEnableOption "enable heracles service"; + services.heracles.listen = mkOption { + description = "[host]:port address for heracles to listen on"; + default = "localhost:8080"; + defaultText = "localhost:8080"; }; - config = mkIf config.services.heracles.enable { - environment.etc."heracles.yaml" = { - text = (generators.toYAML {} config.services.heracles.settings); - }; - systemd.services.heracles = { - wantedBy = [ "multi-user.target" "default.target" ]; - wants = [ "network.target" ]; - after = [ "network-online.target" ]; - serviceConfig = { - Restart = "on-failure"; - RestartSec = "30s"; - ExecStart = "${pkgs.heracles}/bin/heracles --listen ${config.services.heracles.listen} --config=${config.environment.etc."heracles.yaml".target}"; - }; - }; + services.heracles.settings = mkOption { + description = "heracles dashboard Configuration"; + default = [ + { + title = "A dashboard"; + graphs = [ + { + title = "Graph title"; + query_type = "Range"; + # yaxis formatting default for this graph + d3_tick_format = "~s"; + plots = [ + { + source = "http://heimdall:9001"; + query = '' + sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) + ''; + meta = { + name_function = "`\${labels.instance}`"; + named_axis = "y"; + # yaxis formatting for this subplot + d3_tick_format = "~s"; + }; + } + ]; + # span for this graph. + span = { + end = "now"; + duration = "1d"; + step_duration = "10min"; + }; + } + ]; + # default span for dashboard + span = { + end = "now"; + duration = "1d"; + step_duration = "10min"; + }; + } + ]; + defaultText = '' + [ + { + title = "A dashboard"; + graphs = [ + { + title = "Graph title"; + query_type = "Range"; + # yaxis formatting default for this graph + d3_tick_format = "~s"; + plots = [ + { + source = "http://heimdall:9001"; + query = \'\' + sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) + \'\'; + meta = { + name_label = "instance"; + name_prefix = "trace name prefix"; + name_suffix = "trace name suffix"; + named_axis = "y"; + # yaxis formatting for this subplot + d3_tick_format = "~s"; + }; + } + ]; + # span for this graph. + span = { + end = "now"; + duration = "1d"; + step_duration = "10min"; + }; + } + ]; + # default span for dashboard + span = { + end = "now"; + duration = "1d"; + step_duration = "10min"; + }; + } + ] + ''; }; + }; + + config = mkIf config.services.heracles.enable { + environment.etc."heracles.yaml" = { + text = generators.toYAML {} config.services.heracles.settings; + }; + systemd.services.heracles = { + wantedBy = ["multi-user.target" "default.target"]; + wants = ["network.target"]; + after = ["network-online.target"]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = "30s"; + ExecStart = "${pkgs.heracles}/bin/heracles --listen ${config.services.heracles.listen} --config=${config.environment.etc."heracles.yaml".target}"; + }; + }; + }; }; }; } From 63b4f810c2d9e9d61e48636c6c0c9846c13cd586 Mon Sep 17 00:00:00 2001 From: Lucas Bergman Date: Mon, 19 Feb 2024 17:50:39 -0600 Subject: [PATCH 2/4] maint: Set formatter Nix flake output so `nix fmt` works I've idly thought about making the formatter a derivation that runs alejandra over Nix code, then rustfmt over Rust code, etc--so that just running `nix fmt` in the root cleans up everything--but I haven't made that work yet. --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 09901b3..b38c034 100644 --- a/flake.nix +++ b/flake.nix @@ -45,6 +45,7 @@ }; in { packages.default = heracles; + formatter = pkgs.alejandra; }) // { nixosModule = { From 668015ed174a32f4124b89202833c3e243595607 Mon Sep 17 00:00:00 2001 From: Lucas Bergman Date: Mon, 19 Feb 2024 18:01:56 -0600 Subject: [PATCH 3/4] maint: Some Nix flake cleanups Specifically: 1. Switch from the nixosModule flake output (which is deprecated) to nixosModules.default 2. Remove "with lib;" it's convenient, but I've gotten feedback when upstreaming module changes that that shouldn't be a thing in nixpkgs anymore 3. Add a little type checking to the NixOS module options 4. Switch the default config to empty (but leave the example) 5. Use the convention "let cfg = config.services.heracles," a thing that's super common in NixOS --- flake.nix | 94 +++++++++++++++++-------------------------------------- 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/flake.nix b/flake.nix index b38c034..245c5b1 100644 --- a/flake.nix +++ b/flake.nix @@ -48,23 +48,26 @@ formatter = pkgs.alejandra; }) // { - nixosModule = { + nixosModules.default = { config, pkgs, lib, - }: - with lib; { - options = { - services.heracles.enable = mkEnableOption "enable heracles service"; - services.heracles.listen = mkOption { - description = "[host]:port address for heracles to listen on"; - default = "localhost:8080"; - defaultText = "localhost:8080"; - }; + }: { + options = { + services.heracles.enable = lib.mkEnableOption "enable heracles service"; + services.heracles.listen = lib.mkOption { + description = "[host]:port address for heracles to listen on"; + default = "localhost:8080"; + defaultText = "localhost:8080"; + type = lib.types.string; + }; - services.heracles.settings = mkOption { - description = "heracles dashboard Configuration"; - default = [ + services.heracles.settings = lib.mkOption { + description = "heracles dashboard Configuration"; + type = lib.types.listOf lib.types.attrs; + default = []; + defaultText = lib.literalExpression '' + [ { title = "A dashboard"; graphs = [ @@ -76,11 +79,11 @@ plots = [ { source = "http://heimdall:9001"; - query = '' + query = \'\' sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) - ''; + \'\'; meta = { - name_function = "`\${labels.instance}`"; + name_function = "''${labels.instance}"; named_axis = "y"; # yaxis formatting for this subplot d3_tick_format = "~s"; @@ -102,56 +105,17 @@ step_duration = "10min"; }; } - ]; - defaultText = '' - [ - { - title = "A dashboard"; - graphs = [ - { - title = "Graph title"; - query_type = "Range"; - # yaxis formatting default for this graph - d3_tick_format = "~s"; - plots = [ - { - source = "http://heimdall:9001"; - query = \'\' - sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) - \'\'; - meta = { - name_label = "instance"; - name_prefix = "trace name prefix"; - name_suffix = "trace name suffix"; - named_axis = "y"; - # yaxis formatting for this subplot - d3_tick_format = "~s"; - }; - } - ]; - # span for this graph. - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ]; - # default span for dashboard - span = { - end = "now"; - duration = "1d"; - step_duration = "10min"; - }; - } - ] - ''; - }; + ] + ''; }; + }; - config = mkIf config.services.heracles.enable { + config = let + cfg = config.services.heracles; + in + lib.mkIf cfg.enable { environment.etc."heracles.yaml" = { - text = generators.toYAML {} config.services.heracles.settings; + text = lib.generators.toYAML {} cfg.settings; }; systemd.services.heracles = { wantedBy = ["multi-user.target" "default.target"]; @@ -160,10 +124,10 @@ serviceConfig = { Restart = "on-failure"; RestartSec = "30s"; - ExecStart = "${pkgs.heracles}/bin/heracles --listen ${config.services.heracles.listen} --config=${config.environment.etc."heracles.yaml".target}"; + ExecStart = "${pkgs.heracles}/bin/heracles --listen ${cfg.listen} --config=${config.environment.etc."heracles.yaml".target}"; }; }; }; - }; + }; }; } From 94b05b143762e436e6f5342ce12d899cf5a26ba2 Mon Sep 17 00:00:00 2001 From: Lucas Bergman Date: Tue, 20 Feb 2024 07:58:03 -0600 Subject: [PATCH 4/4] maint: NixOS module writes config to the Nix store Instead of writing the config attrset to a YAML file to a fixed path in /etc, this makes the NixOS module write to a (content-addressed) config file in the Nix store. We just use builtins.toJSON since YAML is a superset of JSON. --- flake.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 245c5b1..86b27e7 100644 --- a/flake.nix +++ b/flake.nix @@ -112,11 +112,9 @@ config = let cfg = config.services.heracles; + cfgFile = pkgs.writeText "heracles.yaml" (builtins.toJSON cfg.settings); in lib.mkIf cfg.enable { - environment.etc."heracles.yaml" = { - text = lib.generators.toYAML {} cfg.settings; - }; systemd.services.heracles = { wantedBy = ["multi-user.target" "default.target"]; wants = ["network.target"]; @@ -124,7 +122,7 @@ serviceConfig = { Restart = "on-failure"; RestartSec = "30s"; - ExecStart = "${pkgs.heracles}/bin/heracles --listen ${cfg.listen} --config=${config.environment.etc."heracles.yaml".target}"; + ExecStart = "${pkgs.heracles}/bin/heracles --listen ${cfg.listen} --config=${cfgFile}"; }; }; };